问题
I've been bashing my head against the wall for over an hour and I can't understand why the below doesn't work.
If I change b: db 1 to b: db 0 then it should print 10, otherwise it should print 0. Instead, the program always prints 10.
I've been writing a project that writes assembly and this is one of the unit test that fails and I just don't get it. It has to be something simple.
extern printf, exit
section .bss
section .data
b: db 1
x: dd 5
y: dd 5
z: dd 0
int_pattern: db "%i", 10, 0
global main
section .text
main:
mov eax, dword [b]
cmp eax, dword 0
je condition_end4
; add x and y
; store into z
mov eax, dword [rel x]
add eax, dword [rel y]
mov [rel z], eax
condition_end4:
; rsi = &z
; rdi = &int_pattern
mov rsi, qword [z]
mov rdi, int_pattern
; not using vector registers
xor rax, rax
; printf(int_pattern, z);
call printf
I'm using Debian Linux with NASM. Assembling/linking with
nasm -f elf64 -o test.o test.asm
gcc test.o -o test.bin
Even when b is 0, GDB shows that the cmp unsets ZF so I'm at a loss here.
Thanks!
回答1:
You've declared b as a byte:
b: db 1
but you load it as a dword:
mov eax, dword [b]
This explains why the zero flag is unset even when b is 0: because it's loading the next 3 bytes as well.
Just change your declaration:
b: dd 1
Alternatively, you could load a byte with zero extension: movzx eax, byte [b]
Similarly, you load a qword from z but you only defined it as a dd dword. See Which variable size to use (db, dw, dd) with x86 assembly?
Also, use default rel so all addressing modes pick RIP-relative addressing without having to say [rel b] everywhere.
来源:https://stackoverflow.com/questions/43014135/loading-a-register-from-a-db-0-doesnt-load-a-0-into-eax