调试两个数字中较大数字的汇编代码时出现问题
Trouble debugging assembly code for greater of two numbers
我编写了以下代码来检查第一个数字 - '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作为输出。
我正在使用以下命令 运行 Ubuntu 20.04.1 LTS 和 nasm 2.14.02-1
上的代码
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]
至于
And how should one debug assembly codes
您的主要工具是 assembly-level 调试器,如 EDB on Linux or x64dbg on Windows. But in fact, most debuggers, even the ones intended for languages like C++, are capable of displaying disassembly for the program being debugged. So you can use e.g. GDB,甚至是它的 GUI 包装器,如 Qt Creator 或 Eclipse。只需确保切换到机器代码模式,或使用适当的命令,如 GDB 的 disassemble
、stepi
、info registers
等。
请注意,您不必从源代码构建 EDB 或 GDB(如上面的链接可能建议的那样):它们可能已经打包在您使用的 Linux 发行版中。例如。在 Ubuntu 上,包名为 edb-debugger
and gdb
。
我编写了以下代码来检查第一个数字 - '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作为输出。
我正在使用以下命令 运行 Ubuntu 20.04.1 LTS 和 nasm 2.14.02-1
上的代码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]
至于
And how should one debug assembly codes
您的主要工具是 assembly-level 调试器,如 EDB on Linux or x64dbg on Windows. But in fact, most debuggers, even the ones intended for languages like C++, are capable of displaying disassembly for the program being debugged. So you can use e.g. GDB,甚至是它的 GUI 包装器,如 Qt Creator 或 Eclipse。只需确保切换到机器代码模式,或使用适当的命令,如 GDB 的 disassemble
、stepi
、info registers
等。
请注意,您不必从源代码构建 EDB 或 GDB(如上面的链接可能建议的那样):它们可能已经打包在您使用的 Linux 发行版中。例如。在 Ubuntu 上,包名为 edb-debugger
and gdb
。