2016-06-15 14 views
0

私は自分のエラーを理解しようとしています。私にとっては、このプログラムは正しいようです。私は最初の2つのマクロを追加しました:abin2intとint2abinまた、合計、最小、最大と計算平均。残りはテンプレートです。x86アセンブリエラー

私のエラー: ast06.asm:313:エラー:425:エラー:429:エラー:433:メモリアドレス ast06.asmを期待するメモリアドレス ast06.asmが予想されるメモリアドレスが ast06.asmが予想さ:エラー:メモリアドレスが予想されます

特に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 binaary format 



;  Convert ASCII binary format length to inetger (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 
+2

あなたはどのアセンブラを使用していますか? TASM? NASM? YASM?あなたが提供したコードには433行もありません。エラーは '313'、' 425'、 '429'、および' 433'行で報告されます。これらの行がコード内のどこにあるかを明示せずに、それは私たちのために困難になります! –

+0

これは、私たちが見たいと思う多くのコードです。質問をする前に、可能な限り問題を絞り込むことをお勧めします。チュートリアル:[MCVE]をご覧ください。 –

答えて

1

EDITあなたはNASMを使用している場合は、あなたはあなたのint2abinマクロで問題を持っています。

mov eax, %1 

:私はマクロを変更したい - ( []

%macro int2abin 2 

mov eax, dword[%1] 

をしかし、あなたはそれを呼び出すとき、あなたは角括弧を複製

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

を使用します。それは始まり

コードには次の行があります。

二重引用符( ")を使用して、ほとんどのアセンブラで

add al, "0" 
は、どこかのメモリに格納する必要があり、文字列を意味します - ので、上記 alにどこかのメモリの内容の値を追加しようとしていることになります。

あなたはおそらく望んでいた:

add al, '0' 

単一引用符(')はリテラル文字意味 - ASCII値48 - あなたはalに追加するものです。

+2

私はNASMの二重引用符で動作すると信じています。文字シーケンスを値に変換します。 ''''を_EAX_に移動する場合は、それらをパックして' 0x33323130'を生成する必要があります。 '' 0 ''は0x30を生成するはずです。 –

+0

@Michael私はNASMが嫌いだと言いましたか?ありがとうございました:私は少し深く見えました... –

+0

それはYASMでしたが、私に教えてあげましょう...あなたは救い主です。ありがとう – user1072583