问题描述
我编写了以下代码,以检查第一个数字“ x”是否大于第二个数字“ y”。对于x>y
,输出应为1
,对于x<=y
,输出应为0
。
section .txt
global _start
global checkGreater
_start:
mov rdi,x
mov rsi,y
call checkGreater
mov rax,60
mov rdi,0
syscall
checkGreater:
mov r8,rdi
mov r9,rsi
cmp r8,r9
jg skip
mov [c],byte '0'
skip:
mov rax,1
mov rdi,1
mov rsi,c
mov rdx,1
syscall
ret
section .data
x db 7
y db 5
c db '1',0
但是由于某些原因(当然是从我的角度来看),代码在执行时总是给出0作为输出。
我正在使用以下命令在具有nasm 2.14.02-1的Ubuntu 20.04.1 LTS上运行代码
nasm -f elf64 fileName.asm
ld -s -o fileName fileName.o
./fileName
我在哪里犯了错误?
我应该如何查找一个调试汇编代码,我希望在checkGreater中打印接收到的参数,但事实证明,这本身就是一个令人头疼的问题。
注意:如果有人想知道为什么我不直接在checkGreater中使用x和y,我想将比较范围扩展到用户输入,因此仅以这种方式编写代码。
解决方法
说明
mov rdi,x
mov rsi,y
将x
的地址写入rdi
,并将y
的地址写入rsi
。然后,进一步的代码继续比较地址,该地址始终为x<y
,因为x
是在y
上方定义的。
您应该写的是
mov rdi,[x]
mov rsi,[y]
但是然后您遇到另一个问题:x
和y
变量的长度为1个字节,而目标寄存器的长度为8个字节。因此,简单地执行上述修复将读取多余的字节,从而导致无用的结果。最后的更正是固定变量的大小(写dq
而不是db
),或将它们读取为字节:
movzx rdi,byte [x]
movzx rsi,byte [y]
至于
一个调试汇编代码应该如何
适合您的主要工具是程序集级调试器,例如Linux上的EDB或Windows上的x64dbg。但是实际上,大多数调试器,甚至是用于C ++之类的调试器,都能够显示正在调试的程序的反汇编。所以你可以使用例如GDB,甚至是Qt Creator或Eclipse的GUI包装器。只需确保切换到机器代码模式,或使用适当的命令,例如GDB的disassemble
,stepi
,info registers
等。
请注意,您不必从源代码构建EDB或GDB(如上面的链接可能暗示的那样):它们可能已经打包在您使用的Linux发行版中。例如。在Ubuntu上,这些软件包分别称为edb-debugger
和gdb
。