在X86组件上遇到麻烦



我正在尝试找出我的错误。对我来说,这个程序似乎是正确的。我添加了前两个宏: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

edit 如果您使用的是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的内容。

最新更新