将 16 位复制到内存位置

问题描述 投票:0回答:1

我现在在大学上机器架构课,我们开始学习组装。我们有一个问题:

以下 x86-64 汇编指令会将 A 寄存器中的 16 位复制到 B 寄存器指向的主内存位置。

我的实验室伙伴认为答案是

movw %ax, (%rbx)

因为我们将其复制到的地方是一个指针。

我认为是:

movw %ax, (%bx)

因为这表示它是 16 位。

任何解释都会有帮助,因为我们迷路了,而且没有大量关于此的明确信息!

assembly x86-64 att
1个回答
2
投票

16 位地址大小在 64 位代码中不可用。指针是 64 位。您可以尝试组装

movw %ax, (%bx)
,尽管生成的错误消息
foo.s:1: Error: `(%bx)' is not a valid base/index expression
并不是超级有帮助。 (我使用
gcc -c foo.s
在我的 x86-64 Linux 桌面上运行 GAS。)

地址大小和操作数大小是不同的东西。

mov %ax, (%rbx)
是 RBX 指向的内存的 16 位存储。
%ax
是一个 16 位寄存器,因此它意味着 16 位操作数大小。 (是的,助记符上带有操作数大小覆盖后缀的
movw
也是一种有效的编写方式。)


有趣的事实:

mov %ax, (%ebx)
在64位模式下是可编码的,但它只会使用RBX的低32位作为内存操作数的地址。您基本上永远不想在 64 位模式下使用 32 位地址大小,即使在 LEA 指令中也是如此。

你的实验室伙伴是正确的,它与C完全相似:

  uint16_t *p;
  sizeof(p) == 8        // With a normal x86-64 C compiler
  sizeof(*p) == 2

在寻址模式下,您始终必须使用寄存器的完整大小。使用指针的低 16 位作为寻址模式是没有用的。

没有大量关于此的明确信息!

Intel的手册非常明确,但也相当长。 https://software.intel.com/en-us/articles/intel-sdm# Three-volume

第 2 卷手册主要部分的 HTML 摘录(不含如何阅读部分):https://www.felixcloutier.com/x86/index.html,其中包含

mov 条目
https://www.felixcloutier.com/x86/mov

另请参阅其他链接 https://stackoverflow.com/tags/x86/info

相关:

© www.soinside.com 2019 - 2024. All rights reserved.