新的X86_64处理器寄存器的名称是什么?

68

在这种架构下,我在哪里可以找到汇编语言的新寄存器名称?

我的意思是X86中的寄存器,例如EAX、ESP、EBX等,但我想要64位的。

我认为它们与我反汇编C代码时不同,因为我得到的是带有r的寄存器,而不是e。


各位,当进行系统调用时,我该如何确定哪些寄存器与参数相关联。我已经阅读了文档,但并没有找到明确的答案。 - Recursion
请注意,旧的上8位寄存器(ah、bh等)不再适用于所有操作码。例如,在x64中inc ah是无效的,因为该操作码已被重用于新的64位寄存器之一。 - Johan
1
@Johan:还要注意,使用REX前缀后,ah bh ch dh的寄存器代码将变成新的字节寄存器sil dil bpl spl。 - phuclv
4个回答

113

MSDN文档中包含有关x64寄存器的信息。

x64将x64的8个通用寄存器扩展到64位,并添加了8个新的64位寄存器。64位寄存器的名称以“r”开头,因此例如eax的64位扩展被称为rax。新寄存器的名称为r8到r15。

每个寄存器的低32位、16位和8位直接可在操作数中寻址,这包括像esi这样以前其低8位不可寻址的寄存器。以下表格指定了64位寄存器低部分的汇编语言名称。

64-bit register | Lower 32 bits | Lower 16 bits | Lower 8 bits
==============================================================
rax             | eax           | ax            | al
rbx             | ebx           | bx            | bl
rcx             | ecx           | cx            | cl
rdx             | edx           | dx            | dl
rsi             | esi           | si            | sil
rdi             | edi           | di            | dil
rbp             | ebp           | bp            | bpl
rsp             | esp           | sp            | spl
r8              | r8d           | r8w           | r8b
r9              | r9d           | r9w           | r9b
r10             | r10d          | r10w          | r10b
r11             | r11d          | r11w          | r11b
r12             | r12d          | r12w          | r12b
r13             | r13d          | r13w          | r13b
r14             | r14d          | r14w          | r14b
r15             | r15d          | r15w          | r15b

这很清楚,但是在我的Intel x86-64 CPU上,对于'r8''r15'来说,较低的8位模式似乎无效,尽管其他8个通用寄存器可以使用。此外,'rax''rdx'支持以'high'模式访问8位,这意味着使用'ah'~'dh'访问16位模式的最高有效8位。 - Eric
@EricWang:你试过使用mov ah,r8b或类似的东西吗?你不能在REX前缀中使用高8寄存器。REX mov ah,0就是mov spl,0,以此类推(当有REX前缀时,AH / CH / DH / BH的编码意味着spl / bpl / sil / dil(按照机器代码中的顺序))。 - Peter Cordes
1
请注意,在某些手册中,低8位寄存器称为“l”,而不是“b”,例如“r8l”与“r8b”。请参阅为什么苹果公司将字节寄存器命名为R8l而不是R8b? - phuclv
新的APX扩展现在增加了16个寄存器:r16到r31。 - phuclv

91

旧的32位寄存器已经扩展到64位,包括 r 寄存器 (rax, rbx, rsp 等)。

此外,还有一些额外的通用寄存器,r8r15,可以通过(例如)r8dr8wr8b 访问(分别表示低32位双字、16位字和8位字节)。后缀 b 是原始的 AMD 命名法,但有时会将其写成小写的 l,表示“低字节”。

我自己倾向于使用 b 后缀(即使当前的低字节寄存器是 albl 等),因为它与 d/w = double/word 名称相匹配,而 l 可能会被误解为 long。或者更糟糕的是,数字 1,导致你质疑寄存器号 81 是什么意思 :-)

旧的16位寄存器的高字节在许多情况下仍然可以访问,例如作为 ahbh 等(尽管在新的 r8r15 寄存器中似乎不是这样)。一些新的指令编码,特别是使用 REX 前缀的编码,无法访问这些原始高字节,但其他指令仍然可以使用它们。

此外,还有一些新的 SSE 寄存器,xmm8xmm15

eipeflags 寄存器也已扩展为 riprflags(尽管目前 rflags 的高32位仍未使用)。

更多细节请参见维基百科页面MSDN

我无法确定这些是否在特定C编译器的asm关键字中得到支持。我所做的少量汇编语言(现在每年只有一天)都是用汇编语言而不是C来完成的。


相关:


32
@int80,我不知道。也许 e 意味着扩展的,而 r 则意味着真正的扩展 :-) - paxdiablo
1
我知道 "e" 代表扩展(从16位)。但是 "r" 是什么意思呢?不过你的回答很合乎逻辑 %) - user3151614
1
这是不正确的。当使用 REX 前缀时,您不能使用上半部分 (ah, bh, ch, dh),因为它们被映射到其他寄存器的下半部分 (si, bp, sp, di)。这意味着如果您在 r8 中存储了一个地址,则不能将 ah 的内容移动到该地址。 - Fotis
2
@Fotis,哪一部分“不正确”?如果您指的是x86-64无法在带有REX前缀的指令中访问上半部分(ah等),那么这是我甚至没有涵盖的限制,尽管我会添加一个简短的注释。这只意味着_某些_指令无法访问那些上半部分,而不是寄存器不存在或根本不能使用它们。并且,为了澄清,寄存器本身没有映射,而是指令编码 - 如果更改sil,那不会影响ah内容的后续内容。 - paxdiablo
8
“r”代表寄存器,例如R8、R9、R10等。对于rax到rbp的寄存器,“r”的命名是为了保持一致性。 - vy32
显示剩余12条评论

9
X64将32位通用寄存器扩展如下:
EAX -> RAX
EBX -> RBX
ECX -> RCX
EDX -> RDX
ESI -> RSI
EDI -> RDI
ESP -> RSP
EBP -> RBP

X64还添加了以下64位通用寄存器:

R8, R9, R10, R11, R12, R13, R14, R15

此外,SSE是X64规范的一部分,因此xmm0-xmm15向量寄存器也可用。
您可以在Wikipedia/X86-64上找到有关该体系结构的基本信息,或者访问英特尔网站。

5

让我们阅读英特尔手册

在这个架构上,我在哪里可以找到汇编语言的新寄存器名称。

在处理器的手册“Intel 64和IA-32体系结构软件开发人员手册卷1:基本架构”中,例如版本253665-053US

  • 搜索“registers”
  • 第一个匹配项是索引“3.4基本程序执行寄存器”
  • 在“3.4.1.1 64位模式下的通用寄存器”两个项目以下

在该部分中:

如果指定了64位操作数大小:RAX、RBX、RCX、 RDX、RDI、RSI、RBP、RSP、R8-R15可用。R8D-R 15D/R8-R15代表八个新的通用寄存器。

提醒:在x86-64中,64位模式是“正常”模式。另一个主要模式是“兼容模式”,它模拟IA32。
如果您继续在TOC上搜索“register”,您还会在手册中找到关于浮点和SIMD的“number crushing”寄存器的章节:
8.1.2 - x87 FPU数据寄存器(STx) 9.9.2 - MMX寄存器 10.2.2 - XMM寄存器 14.1.1 - 256位宽SIMD寄存器支持(YMM)
还有许多控制寄存器具有各种副作用,通常情况下不能写入,除非您需要这些效果(而且通常需要ring 0)。这些内容总结在“第3卷系统编程指南-2.1.6系统寄存器”中,更适合操作系统开发人员。
一个好的经验方法是在GDB中运行info all-registers命令:如何在GDB中打印寄存器的值?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接