assembly - 将 16 位复制到内存位置

标签 assembly x86-64 att

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

The following x86-64 assembly instruction will copy 16 bits from the A register to the main memory location pointed to by the B register.

我的实验室合作伙伴认为答案是movw %ax, (%rbx)
因为我们将其复制到的地方是一个指针。

我认为是:movw %ax, (%bx)
因为这表示它是 16 位。

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

最佳答案

16 位地址大小在 64 位代码中不可用。指针是 64 位的。您可以尝试组装 movw %ax, (%bx) ,尽管生成的错误消息是 foo.s:1: Error: `(%bx)' is not a valid base/index expression并不是 super 有帮助。 (我使用 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 位作为寻址模式是没有用的。

there's not a ton of explicit information on this!

英特尔的手册非常明确,但也很长。 https://software.intel.com/en-us/articles/intel-sdm#three-volume

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

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

相关:

关于assembly - 将 16 位复制到内存位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58386524/

相关文章:

linux - 将 16 位 DOS x86 程序集移植到 32 位 Linux x86 程序集

c - 如何创建我自己的库以开始使用操作系统?

assembly - leal(%eax,%eax) 是做什么的?

variables - 如何在 Z80 程序集中创建变量?

c - 如何在信号处理程序中获取执行上下文?

assembly - 汇编 : operand size mismatch for 'out' error

c - 将表存储在不同的内存地址 - AVR XMEGA256A3BU 的 C

c - 如何在x86-64架构上使用INVLPG?

x86 - 将 _mm_shuffle_epi32 转换为 C 表达式以进行排列?

assembly - MOV(%r11,%r12,1),%edx是什么意思?