Loading a register from a “db 0” doesn't load a 0 into EAX?

旧街凉风 提交于 2020-11-29 10:56:38

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!