按照关于汇编寄存器大小的答案:
首先,在 64 位体系结构中
eax
,ax
、ah
及其对应物的大小是多少?如何访问单个寄存器的字节以及如何访问所有 64 位寄存器的 8 个字节?我很想关注x86-64 (x64)和Itanium处理器。
其次,在新的调用约定中,使用四个寄存器来保存函数调用中的前四个参数的正确方法是什么?
按照关于汇编寄存器大小的答案:
首先,在 64 位体系结构中eax
,ax
、ah
及其对应物的大小是多少?如何访问单个寄存器的字节以及如何访问所有 64 位寄存器的 8 个字节?
我很想关注x86-64 (x64)和Itanium处理器。
其次,在新的调用约定中,使用四个寄存器来保存函数调用中的前四个参数的正确方法是什么?
使用旧名称时,所有寄存器的大小都保持不变,就像 x86-16 扩展到 x86-32 时一样。要访问 64 位寄存器,请使用带有R 前缀的新名称,例如 rax、rbx...
寄存器名称不会改变,因此您只需像以前一样将字节寄存器(al、bl、cl、dl、ah、bh、ch、dh)用于 ax、bx、cx、dx 的 LSB 和 MSB。
还有8 个新寄存器,称为 r8-r15。您可以通过添加后缀来访问它们的 LSB b
(或者l
如果您使用的是 AMD)。比如 r8b, r9b... 你也可以使用 esi, edi, esp, ebp 的 sil, dil, spl, bpl 的 LSB 和新的REX 前缀,但是不能和 ah 同时使用, bh、ch 或 dh。
同样,可以通过后缀w
或访问新寄存器的最低字或双字d
。
关于调用约定,在特定系统上只有一个约定1。
1自 MSVC 2013 以来,Windows上还有一个新的扩展约定__vectorcall
,因此“单一约定政策”不再适用。
在 Linux 和其他遵循System V AMD64 ABI的系统上,可以在寄存器上传递更多参数,并且堆栈下方有一个 128 字节的红色区域,这可能会使函数调用更快。
有关更多信息,请阅读x86-64和x86-64 调用约定
计划 9中还使用了一个约定,其中
- 所有寄存器都是调用者保存的
- 所有参数都在堆栈上传递
- 返回值也返回到堆栈中,在参数下方保留的空间中(堆栈方式;amd64 上的更高地址)。
事实上,Plan 9 一直都是个怪人。例如,它在没有硬件零寄存器的 RISC 架构上强制寄存器为 0。它上面的 x86 寄存器名称在 16、32 和 64 位 x86 架构中也是一致的,操作数大小由助记符后缀指示。这意味着 ax 可以是 16、32 或 64 位寄存器,具体取决于指令后缀。如果您对此感到好奇,请阅读
OTOH Itanium是一个完全不同的架构,与 x86-64 没有任何关系。它是纯 64 位架构,因此所有普通寄存器都是 64 位的,没有 32 位或更小的版本可用。里面有很多寄存器:
- 128 个通用整数寄存器 r0 到 r127,每个寄存器携带 64 个值位和一个陷阱位。稍后我们将了解有关陷阱位的更多信息。
- 128 个浮点寄存器 f0 到 f127。
- 64 个谓词寄存器 p0 到 p63。
- 8 个分支寄存器 b0 到 b7。
- 一个指令指针,Windows 调试引擎出于某种原因将其称为 iip。(额外的“i”代表“疯狂”?)
- 128个专用寄存器,并非所有的都被赋予了意义。出于某种原因,这些被称为“应用程序寄存器”(ar)。我将介绍讨论期间出现的选定寄存器。
- 其他杂项寄存器我们不会在本系列中介绍。
阅读更多关于x64 和 IA-64 有什么区别?