1

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!

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
bk5115545
  • 59
  • 7

1 Answers1

6

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.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
samgak
  • 23,944
  • 4
  • 60
  • 82