当前位置: 首页 > 知识库问答 >
问题:

MOV指令的x86-64编码,大小写奇怪

况浩邈
2023-03-14

我反汇编(使用objdump -d)这个操作码(c7 45 fc 05 00 00 00)并得到这个(移动DWORD PTR [rbp-0x4],0x5)。然后我尝试解码自己,我认为应该是(移动DWORD PTR [ebp-0x4],0x5)。为什么它是RBP寄存器而不是EBP寄存器?我错过了什么吗?

在这里,我尝试:首先,我看看C7操作码的mov操作码。

C7 /0 iw |视场角 r/m16,imm16

C7 /0id|MOV r/m32, ym32

雷克斯。W C7/0 id | MOV r/m64,imm32

所以没有雷克斯。w前缀,这里也没有rb,rw,rd,ro。/0意味着ModR/M字节只使用R/M寄存器,reg/opcode字段在这里可以安全地忽略。所以0x45转换成[EBP] disp8(使用表2-2。第2卷/第2章中modR/M字节的32位寻址形式)。disp8是0xfc -

共有1个答案

洪研
2023-03-14

在64位模式下,默认地址大小为64位:如果没有地址大小覆盖前缀(即67h,而不是REX. W),寄存器的64位变体将用于地址计算。这很好,您几乎总是希望在64位模式下进行64位地址计算,如果这不是默认值,那么就会有很多前缀被浪费。REX. W前缀不影响地址大小,但“操作大小”,REX. W C7…mov QWORD PTR[…],im32的编码。

因此,当为64位模式进行组装时,0x5将被编码为67 c7 45 fc 05 00 00 00,当为64-bit模式反汇编c7 45 fc05 00 00 0064位模式时,它意味着移动DWORD PTR[RBP-0x4],0x5。

这些默认值的一个有趣结果是lea的最短形式使用64位地址但32位目标,一开始看起来有点错误。

 类似资料:
  • 当我们在汇编中使用mov指令时,源操作数和目标操作数的大小必须相同。如果我写: 转换的1操作数是否与rax寄存器的大小有关?

  • 背景: 在使用嵌入式汇编语言优化某些Pascal代码时,我注意到一条不必要的MOV指令,并将其删除。 令我惊讶的是,删除不必要的指令导致我的程序速度减慢。 我发现添加任意、无用的指令会进一步提高性能。 效果是不稳定的,并且基于执行顺序的更改:由单行向上或向下转置的相同垃圾指令会产生减速。 我知道CPU会进行各种优化和精简,但这更像是黑魔法。 数据: 我的代码的一个版本在一个循环的中间有条件地编译了

  • 我对指令流水线有些怀疑。 我有一个集会

  • 我阅读了关于64位模式下地址计算的英特尔手册。假设我们有64位模式,默认地址大小是64位。另外,假设所讨论的指令前面有地址大小覆盖前缀,因此地址大小变成32位。 现在,假设指令用寄存器号0(RAX/EAX/AX...)指定的地址编码内存操作数。 现在我不完全理解的是,CPU是只查看eax值并在内部扩展它以形成“本地”64位地址,还是查看整个rax值并将其截断到有效的32位范围(例如,rax包含类似

  • 问题内容: 我最近正在构建针对x86-64架构的特定共享库(ELF),如下所示: 失败并显示以下错误: 创建共享库时,不能使用针对“本地符号”的R_X86_64_32重定位;用-fPIC重新编译 当然,这意味着我需要将其重建为位置无关的代码,因此适合链接到共享库。 但这在具有完全相同的构建参数的x86上效果很好。所以问题是,x86上的重定位与x86-64有何不同?为什么我不需要在前一个上进行编译?

  • 我在横梁上找到了一条评论。 从Intel的Sandy Bridge开始,spatial prefetcher现在一次提取64字节缓存线对,因此我们必须将其对齐到128字节,而不是64字节。 来源: https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimizat