gpt4 book ai didi

linux - NASM Assembly 64 位 Linux 中的比较

转载 作者:太空宇宙 更新时间:2023-11-04 10:49:56 29 4
gpt4 key购买 nike


我正在通过乔纳森·巴特利特 (Jonathan Bartlett) 的书从头开始编程 ( Link ) 学习汇编程序,并且我尝试将 32 位 AT&T 语法转换为 64 位英特尔语法版本。我使用 NASM。现在我正在努力让第 3 章的第二个程序(返回数字序列的最大数量)在 64 位 Intel 上工作。我修改了很多代码,最终设法缩小了问题的范围:这是两个数字的比较和条件跳转。这是演示问题的非常简单的版本:

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

我从内存中读取了一个数字(数据,数字为0)。但是当我把这个 0 和 0 进行比较时,计算机显然看到了我看不到的差异。我确定此时 rdi 包含 0,因为当我在那里退出程序并使用

获取它的返回值时
echo $?

它打印 0。如果有人对这种神秘行为有任何提示,我将不胜感激。另外,如果你知道一个调试汇编代码的好工具,也请告诉我,因为一直重写程序只是为了在每个时刻获取寄存器的值是非常烦人的......

PS:我知道 Intel 语法并不常用于 Linux,但我选择它是因为它对我来说看起来更清晰,而且 Vim 中的源代码突出显示对于 NASM 比 AT&T 好得多;-)

最佳答案

mov rdi, [data] 将从内存中加载 8 个字节,因为这是 rdi 的大小。但是,您仅使用 db 声明了 1 个字节。您可以通过 3 种方式修复它:

  1. 使用dq 0定义所有8个字节。
  2. 使用 movzx rdi, byte [data] 将字节零扩展为 qword。
  3. 使用 mov dil, [data]cmp dil​​, 0 仅加载和比较单个字节。

请注意,退出代码仅提供低 8 位,这就是您看不到错误的原因。学习改用调试器,这样您就可以单步执行代码并检查每个点的寄存器。

关于linux - NASM Assembly 64 位 Linux 中的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31394452/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com