将常量字节值移动到 %ebx 时出错

Pet*_*yas 6 assembly x86-64 addressing-mode

我正在研究计算机系统,程序员的观点(第 3 版),练习题 3.3 包含以下行:

movb $0xF, (%ebx)
Run Code Online (Sandbox Code Playgroud)

我应该找出这行 x86-64 汇编代码有什么问题,答案是:“不能使用 %ebx 作为地址寄存器”,这对我来说没有意义。我的理解是这一行打算将 0xF 复制到主内存中的某个位置,但是 %ebx 是一个 32 位寄存器,64 位机器上的内存地址是 64 位宽,因此 %ebx 不能保存内存地址,因此它不能被取消引用(取消引用是 %ebx 周围的括号所代表的,对吗?)。然而,翻开书中的几页(第 183 页,如果你有的话)有一个例子详细说明了五个 mov 操作数 - 目标组合,其中之一是:

movb $-17, (%esp)         Immediate--Memory, 1 byte
Run Code Online (Sandbox Code Playgroud)

%esp 是一个 32 位寄存器,就像 %ebx! 这个例子显示了一个字节值被移动到一个取消引用的 32 位寄存器!这对我来说没有意义,因为 %esp 如何包含 64 位地址?我完全误解了汇编吗?

小智 5

你说得对,

movb $-17, (%esp)         Immediate--Memory, 1 byte
Run Code Online (Sandbox Code Playgroud)

不应该被允许。事实上,作者已将此作为错别字发布。查看他们的勘误表(Ctrl-F 表示“第 183 页”)。

  • 它是可编码的,但通常会出错,除非 `%rsp` 的高 32 位为零。如果您的堆栈位于低 4G 内存中,就会出现这种情况。[Linux x32 ABI](https://en.wikipedia.org/wiki/X32_ABI) 在 64 位模式下使用 32 位指针(以节省大量指针代码中的缓存占用空间,并在使用指针时避免使用 REX 前缀),所以这在那里是有效的。无论如何,我认为你的意思是说这不是一个很好的例子。感谢更新,这是书中的一个错误。 (2认同)