簡體   English   中英

x86 組裝有問題

[英]Having trouble with x86 assembly

我試圖找出我的錯誤。 對我來說,這個程序似乎是正確的。 我添加了前兩個宏的:abin2int 和 int2abin 此外,還有總和、最小值、最大值和計算平均值。 其余為模板。

我的錯誤:

ast06.asm:313: 錯誤: 預期內存地址
ast06.asm:425: 錯誤: 預期內存地址
ast06.asm:429: 錯誤: 預期內存地址
ast06.asm:433: 錯誤: 預期內存地址

它專門調用 int2abin。 我似乎無法動搖這一點。 有沒有人有任何想法?

;  Arguments:
;   %1 -> <string>, register -> string address
;   %2 -> <integer>, register -> result


;  Macro usgae
;   abin2int  <string>, <integer>

;  Example usage:
;   abin2int    rbx, tmpInteger

;  For example, to get address into a local register:
;       mov rsi, %1

;  Note, the register used for the macro call (rbx in this example)
;  must not be altered before the address is copied into
;  another register (if desired).

%macro  abin2int    2

mov ebx, %1     ; Index
mov rax, 0      ; rSum
mov ecx, 1

%%binLP: 
movzx   r8d, byte[rbx] ; getChr
cmp r8d, NULL      ; r8b == NULL
je  %%exitQLP
sub r8d, "0"    ; IntVal
mul ecx     ; rSum = rSum * 4
add eax, r8d    ; rSum + IntVal
inc ebx
jmp %%binLP

%%exitQLP:  
mov dword[%2], eax


%endmacro



; =====================================================================
;  Macro to convert integer to hex value in ASCII format.
;  Reads <integer>, converts to ASCII/binary string including
;   NULL into <string>
;  Note, macro should preserve any registers that the macro alters.

;  Arguments:
;   %1 -> <integer>, value
;   %2 -> <string>, string address

%macro  int2abin    2

mov eax, dword[%1]
mov ecx, 4
mov r9d, STRLENGTH
mov r10d, STRLENGTH
dec r9d
dec r10d
mov r11, 0

%%intLP:
mov edx, 0
cmp r9d, 0
je  %%int2LP
cdq
div ecx
push    rdx
dec r9d
jmp %%intLP

%%int2LP:
cmp r10d, 0
je  %%null
pop rax
add al, "0"
mov byte[%2+r11], al
inc al
inc r11
dec r10d
jmp %%int2LP

%%null:
mov byte[%2+r11], al


%endmacro

; =====================================================================
;  Simple macro to display a string to the console.
;  Count characters (excluding NULL).
;  Display string starting at address <stringAddr>

;  Macro usage:
;   printString  <stringAddr>

;  Arguments:
;   %1 -> <stringAddr>, string address

%macro  printString 1
push    rax         ; save altered registers
push    rdi
push    rsi
push    rdx
push    rcx

lea rdi, [%1]       ; get address
mov rdx, 0          ; character count
%%countLoop:
cmp byte [rdi], NULL
je  %%countLoopDone
inc rdi
inc rdx
jmp %%countLoop
%%countLoopDone:

mov rax, SYS_write      ; system call for write (SYS_write)
mov rdi, STDOUT     ; standard output
lea rsi, [%1]       ; address of the string
syscall             ; call the kernel

pop rcx         ; restore registers to original values
pop rdx
pop rsi
pop rdi
pop rax
%endmacro

; =====================================================================
;  Initialized variables.

section .data

; -----
;  Define standard constants.

TRUE        equ 1
FALSE       equ 0

SUCCESS     equ 0           ; successful operation
NOSUCCESS   equ 1           ; unsuccessful operation

STDIN       equ 0           ; standard input
STDOUT      equ 1           ; standard output
STDERR      equ 2           ; standard error

SYS_read    equ 0           ; system call code for read
SYS_write   equ 1           ; system call code for write
SYS_open    equ 2           ; system call code for file open
SYS_close   equ 3           ; system call code for file close
SYS_fork    equ 57          ; system call code for fork
SYS_exit    equ 60          ; system call code for terminate
SYS_creat   equ 85          ; system call code for file open/create
SYS_time    equ 201         ; system call code for get time

LF      equ 10
SPACE       equ " "
NULL        equ 0
ESC     equ 27

NUMS_PER_LINE   equ 2


; -----
;  Assignment #6 Provided Data

STRLENGTH   equ 32

cSides      db  "00000000000000000000000010101001", NULL
    db  "00000000000000000000000001010101", NULL
    db  "00000000000000000000000101011001", NULL
    db  "00000000000000000000000000101010", NULL
    db  "00000000000000000000010101101011", NULL
    db  "00000000000000000001010100101101", NULL
    db  "00000000000000000000000101101101", NULL
    db  "00000000000000000000101011111000", NULL
    db  "00000000000000000000111100111001", NULL
    db  "00000000000000000001001111001101", NULL
    db  "00000000000000000001110001111101", NULL
    db  "00000000000000000000101111100000", NULL
    db  "00000000000000000000110011111001", NULL
    db  "00000000000000000011101001000101", NULL
    db  "00000000000000000000011101011101", NULL
    db  "00000000000000000010110011111000", NULL
    db  "00000000000000000001110101111101", NULL
    db  "00000000000000000001010001111101", NULL
    db  "00000000000000000011110001111101", NULL
    db  "00000000000000000001010001101101", NULL
    db  "00000000000000000001100001111101", NULL

aLength     db  "00000000000000000000000000010101", NULL
length      dd  0

cubeAreasSum    dd  0
cubeAreasAve    dd  0
cubeAreasMin    dd  0
cubeAreasMax    dd  0

; -----
;  Misc. variables for main.

hdr     db  LF, "-----------------------------------------------------"
    db  LF, ESC, "[1m", "CS 218 - Assignment #6", ESC, "[0m", LF
    db  "Cube Area Information", LF, LF
    db  "Cube Sides's:", LF, NULL
shdr        db  LF, "Cube Area's Sum:   ", NULL
avhdr       db  LF, "Cube Areas's Ave:  ", NULL
minhdr      db  LF, "Cube Areas's Min:  ", NULL
maxhdr      db  LF, "Cube Areas's Max:  ", NULL

tmpInteger  dd  0
newLine     db  LF, NULL
spaces      db  "   ", NULL

; Additional variables (if any)

conSix      dd  6

; =====================================================================
;  Uninitialized variables

section .bss

cubeAreas   resd    21
tempString  resb    33

; **************************************************************

section .text
global  _start
_start:

; -----
;  Display assignment initial headers.

mov edx, 0
printString hdr

; -----
;  Convert integer length, in ASCII binary format



;       Convert ASCII binary format length to integer (no macro)
;       Do not use macro here...

mov rbx, aLength    ; Index
mov rax, 0      ; rSum
mov ecx, 1

calc: 
movzx   r8d, byte[rbx] ; getChr
cmp r8d, NULL      ; r8b == NULL
je  exitLP
sub r8d, "0"    ; IntVal
mul ecx     ; rSum = rSum * 4
add eax, r8d    ; rSum + IntVal
inc rbx
jmp calc

exitLP: 
mov dword[length], eax

; -----
;  Convert cube sides from ASCII/binary to integer

mov ecx, dword [length]
mov rdi, 0                  ; index for cube areas
mov rbx, cSides
cvtLoop:
abin2int    rbx, tmpInteger

mov eax, dword [tmpInteger]
mul eax
mov r10, 6
mul r10d
mov dword [cubeAreas+rdi*4], eax
add ebx, (STRLENGTH+1)

inc rdi
dec ecx
cmp ecx, 0
jne cvtLoop

; -----
;  Display each the cube area (two per line).

mov ecx, dword [length]
mov rsi, 0
printLoop:
int2abin    dword [cubeAreas+rsi*4], tempString
printString tempString
printString spaces

test    rsi, 1              ; even/odd check
je  skipNewline
printString newLine
skipNewline:
inc rsi
dec ecx
cmp ecx, 0
jne printLoop
printString newLine

; -----
;  Find sum, min, max and compute average.


;cubeAreas[ i] = 6 * sides[ i]* sides[i]
mov ecx, dword[length]
mov rsi, 0

Calc:
movzx eax, byte[cSides+rsi]
movzx ebx, byte[cSides+rsi]     
mul ebx
mul byte[conSix]
mov dword[cubeAreas+rsi*4],eax

inc rsi
dec ecx
cmp ecx,0
jne Calc

;  Sum, min, and max

mov eax, word[cubeAreas]
mov word[cubeAreasMin], eax
mov word[cubeAreasMax], eax

mov ecx, dword[length]
mov rsi, 0

SLatLP:
mov eax, dword[cubeAreas+rsi*4]
add dword[cubeAreasSum], eax
cmp eax, dword[cubeAreasMin]
jae notNewCaMin
mov dword[cubeAreasMin], eax

notNewCaMin:
cmp eax, dword[cubeAreasMax]
jbe notNewCaMax
mov dword[cubeAreasMax], eax

notNewCaMax:

inc rsi
dec ecx
cmp ecx, 0
jne SLatLP

;  Average
mov eax, dword[cubeAreasSum]
mov edx, 0
div dword[length]
mov dword[cubeAreasAve], eax

; -----
;  Convert sum to ASCII/binary for printing.

printString shdr

mov eax, dword[cubeAreasSum]
mov ecx, 4
mov r9d, STRLENGTH
mov r10d, STRLENGTH
dec r9d
dec r10d
mov r11, 0

int1LP:
mov edx, 0
cmp r9d, 0
je  int2LP
cdq
div ecx
push    rdx
dec r9d
jmp int1LP

int2LP:
cmp r10d, 0
je  nulltime
pop     rax
add al, "0"
mov byte[tempString+r11], al
inc al
inc r11
dec r10d
jmp int2LP

nulltime:
mov byte[tempString+rsi], al




; -----
;  Convert average, min, and max integers to ASCII/binary for printing.

printString avhdr
int2abin    dword [cubeAreasAve], tempString
printString tempString

printString minhdr
int2abin    dword [cubeAreasMin], tempString
printString tempString

printString maxhdr
int2abin    dword [cubeAreasMax], tempString
printString tempString

printString newLine
printString newLine


; *****************************************************************
;  Done, terminate program.

last:
mov rax, SYS_exit
mov rbx, SUCCESS
syscall

編輯如果您使用的是 NASM,那么您的int2abin宏就會出現問題。 它開始:

%macro  int2abin    2

mov eax, dword[%1]

但是當你調用它時,你使用

int2abin    dword [cubeAreas+rsi*4], tempString
...
int2abin    dword [cubeAreasAve], tempString

這重復了方括號 ( [] ) - 所以我將宏更改為:

mov eax, %1

您的代碼具有以下行:

add al, "0"

在大多數匯編程序中,使用雙引號 ( " ) 意味着需要將字符串存儲在內存中的某處 - 因此上面將嘗試將某些內存的內容的值添加到al

你可能想要:

add al, '0'

單引號 ( ' ) 表示字符文字 - ASCII 值 48 - 這是您要添加到al

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM