无法调试两个以上数字的汇编代码

问题描述

我编写了以下代码,以检查第一个数字“ 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]

但是然后您遇到另一个问题:xy变量的长度为1个字节,而目标寄存器的长度为8个字节。因此,简单地执行上述修复将读取多余的字节,从而导致无用的结果。最后的更正是固定变量的大小(写dq而不是db),或将它们读取为字节:

movzx rdi,byte [x]
movzx rsi,byte [y]

至于

一个调试汇编代码应该如何

适合您的主要工具是程序集级调试器,例如Linux上的EDB或Windows上的x64dbg。但是实际上,大多数调试器,甚至是用于C ++之类的调试器,都能够显示正在调试的程序的反汇编。所以你可以使用例如GDB,甚至是Qt Creator或Eclipse的GUI包装器。只需确保切换到机器代码模式,或使用适当的命令,例如GDB的disassemblestepiinfo registers等。

请注意,您不必从源代码构建EDB或GDB(如上面的链接可能暗示的那样):它们可能已经打包在您使用的Linux发行版中。例如。在Ubuntu上,这些软件包分别称为edb-debuggergdb