【问题标题】:movq and 64 bit numbers [duplicate]movq 和 64 位数字
【发布时间】:2013-11-04 03:32:23
【问题描述】:

当我写入寄存器时,一切都很好,

movq  $0xffffffffffffffff, %rax

但我得到错误:当我写入内存位置时,操作数大小不匹配,

movq  $0xffffffffffffffff, -8(%rbp)

这是为什么呢?我在编译后的 C 代码中看到,在 asm 中这些数字被分成两部分,并且出现了两条 movl 指令。

也许您可以告诉我 mowq 和其他说明的文档记录在哪里。

【问题讨论】:

  • @jww:你错过了删除“谢谢”绒毛和其他填充物。如果您根本不想编辑旧帖子,请务必将其删除 (meta.stackoverflow.com/questions/288160/no-thanks-damn-it)。
  • 0xffffffffffffffff 可表示为符号扩展的 imm32 (-1)。我认为您在没有实际测试这个特定常量的情况下编写了这个示例,因为 gas 版本 2.29.1 可以很好地组装它; 48 c7 45 f8 ff ff ff ff movq $0xffffffffffffffff,-0x8(%rbp)(从 objdump 反汇编)。 如果高 32 位不是第 31 位的所有副本,那么它就不能使用内存目标进行编码。
  • 顺便说一句,mov r64, imm64 的 AT&T 助记符是 movabs。当您使用 64 位寄存器目标时,英特尔语法汇编器会根据常量选择编码。

标签: assembly x86 x86-64 att instruction-set


【解决方案1】:

这是为什么呢?

因为MOV r64, imm64 是有效的x86 指令,但MOV r/m64, imm64 不是(没有编码)。


我在编译的 C 代码中看到,在 asm 中这些数字被分成两部分,并且出现了两条 movl 指令。

MOV r/m64, imm32 是一条有效的 x86 指令,这就是为什么您会看到其中两条指令用于将 64 位立即数存储到内存中。


也许你可以告诉我 mowq 和其他说明的记录在哪里

在Intel's Software Developer Manuals。

【讨论】:

  • 谢谢,但是没有这条指令的逻辑是什么?
  • Intel 认为这样的指令不会很有用,所以他们选择不在其上浪费稀缺的指令编码。
  • @markgz:AMD 设计了 ​​x86-64 ISA 扩展,而不是 Intel。但是,是的,他们决定大多数 64 位指令仍将使用 32 位立即数(符号扩展),因为大常量很少见(并且 64 位地址通常由 RIP-relative LEA 处理)。但是,是的,5 字节 mov r32,imm32 特殊编码的 REX.W=1 版本(操作码字节中的寄存器号)变为 mov r64, imm64,而 REX.W=1 mov r/m32, imm32 变为 mov r/m64, sign_extended_imm32。已经有两种不同的操作码可以将立即数移动到寄存器中,因此 AMD 占了上风。
猜你喜欢
  • 2017-03-11
  • 1970-01-01
  • 2019-02-25
  • 2019-07-09
  • 2016-09-14
  • 2013-03-24
  • 2012-07-26
  • 2011-04-20
  • 2010-11-02
相关资源
最近更新 更多