简体   繁体   中英

Comparisons in NASM Assembly 64bit Linux


I am learning Assembler with the book Programming from the Ground Up ( Link ) by Jonathan Bartlett and I try to convert the 32bit AT&T Syntax to the 64bit Intel Syntax version as I go. I use NASM. Right now I am struggeling to get the second program of chapter 3 (return the maximum number of a sequence of numbers) to work in 64bit Intel. I have tinkered around a lot with the code and finally managed to narrow down the problem: It's the comparison of two numbers and the conditional jump. This is a very simple version that demonstrates the problem:

section .data
  data: db 0

section .text
  global _start

_start:
  mov rdi, [data] ; if I exit here, the return value (=rdi) is 0
  cmp rdi, 0
  je  .equals     ; this is not executed
  jz  .equals     ; this neither
  jmp .notEquals

.equals:
  mov rax, 60
  mov rdi, 1
  syscall

.notEquals:       ; this is the result I get
  mov rax, 60
  mov rdi, 2
  syscall

I read a number from memory (data, the number is 0). But when I compare this 0 with 0, the computer obviously sees a difference I can't see. I am sure that rdi contains 0 at this moment because when I exit the program there and get it's return value with

echo $?

it prints 0. I would be very grateful if somebody has any hints about this mysterious behaviour. Also, if you know a nice tool for debugging assembler code, let me know as well because rewriting the program all the time just to get the values of the registers at each moment is very annoying...

PS: I know that the Intel syntax is not commonly used for Linux but I chose it because it looks cleaner to me and also the source highlighting in Vim is much better for NASM than for AT&T ;-)

mov rdi, [data] will load 8 bytes from memory because that's the size of rdi . However you only declared 1 byte using db . You can fix it in 3 ways:

  1. Use dq 0 to define all 8 bytes.
  2. Use movzx rdi, byte [data] to zero extend the byte to a qword.
  3. Use mov dil, [data] and cmp dil, 0 to only load and compare a single byte.

Note that the exit code only provides the low 8 bits, that's why you don't see the error. Learn to use a debugger instead, so you can single step the code and examine the registers at each point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM