X64指令与X86指令兼容,因此不再对X86指令结构重复描述,主要以讲解X64上新特性为主。
x64指令机器码,在原来X86 32位基础上,增加了Rex Prefix,如下所示:
AMD推出 x86 扩展 64 位技术时,增加了一个用于访问扩展的 64 位数据 prefix,它是:REX prefix,而 x86 原有的 prefix 则变为了指令格式中的:Legacy prefix。
REX prefix 仅存在于 x64 的 64-bit 模式中,在 legacy x86 模式下,REX prefix 是无效的。 Legacy prefix在 x86 和x64下,均是有效的。
REX prefix 的取值范围是:40H - 4FH。在非 64 位模式下,它们是 inc 与 dec 指令;也就是说这些指令在 64 位模式下被重定义为 REX prefix,关于Prefix的介绍真的是少之又少,不过可以在x86/x64 指令编码内幕(适用于 AMD/Intel)学到很多。
这里就简单说一下吧,一个Legacy prefix还有一个REX prefix。这些修饰符是为了改变缺省的寄存器,比如说在32位下mov ax,bx。那么就要有Legacy prefix 0x66修饰,前者还有个作用就是改变当前段寄存器,不多这在目前已经显得不怎么重要了。
到了x64的时候,由于通用寄存器的扩展(主要原因),原本的8个通用寄存器只要3个位来标识,但是现在多了r8~r15,16个通用寄存器怎么办呢,很明显加上一位就能完全标识了。
那么就是REX prefix的作用,看一下这个家伙的结构:
各个位的含义,如下:
他有取值范围,前4位一定是4,后四位可选,W,R,X,B。
REX prefix=0100WRXB,扩展位WRXB的使用场景,有以下4种。
r8(/r) r16(/r) r32(/r) r64(/r) mm(/r) |
AL AX EAX RAX MM0 |
CL CX ECX RCX MM1 |
DL DX EDX RDX MM2 |
BL BX EBX RBX MM3 |
AH SP ESP RSP MM4 |
CH BP EBP RBP MM5 |
DH SI ESI RSI MM6 |
BH DI EDI RDI MM7 |
r8b r8w r8d r8 |
r9b r9w r9d r9 |
r10b r10w r10d r10 |
r11b r11w r11d r11 |
r12b r12w r12d r12 |
r13b r13w r13d r13 |
r14b r14w r14d r14 |
r15b r15w r15d r15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Rrrr | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 |
比如:mov r9,r8
,机器码:4D 8B C8
ModRM.reg与ModRM.r/m的扩展与上文描述完全一致,不再赘述。
比如:mov rax,[rbx+rcx*2]
,机器码:48 8B 04 4B
比如:mov rax,4
,机器码:48 C7 C0 04 00 00 00
需要将REX.B与reg合并为4位Bbbb,可以表示16个寄存器。Bbbb为X64架构下寄存器的编号。
X64架构的寻址模式与X86类似,但不完全等同,X64架构提供了一种新的rip相对寻址模式(RIP-Relative),引用单常量地址的指令,被编码为基于rip的偏移量(offsets)。
例如:
mov rax, [addr] ;指令移动以addr+rip为起始地址的8字节内容到rax寄存器。
在64位模式下,RIP-Relative寻址,实现了一种新的寻址形式,rip相对(相对指令指针)寻址。有效的地址,是通过在下一条指令的64位RIP上增加位移来形成的。在IA-32体系结构和兼容模式下,相对于指令指针的寻址只适用于控制转移指令。
在64位模式下,使用ModR/M寻址的指令可以使用rip相对寻址。没有rip相对寻址,所有ModR/M指令模式都相对于零寻址内存。
RIP相对寻址允许特定的ModR/M模式使用带符号的32位位移来寻址相对于64位RIP的内存。这提供了与RIP的±2GB的偏移范围。rip相对寻址的ModR/M和SIB编码如下表所示。在当前的ModR/M和SIB编码中存在32位位移寻址的冗余形式。有一种ModR/M编码和几种SIB编码。rip相关寻址使用冗余形式进行编码。在64位模式下,ModR/M Disp32(32位位移)编码被重新定义为RIP+ Disp32,而不仅是位移。
rip相对寻址的ModR/M编码不依赖于使用前缀。具体来说,101B的r/m位域编码(用于选择rip相对寻址)不受REX前缀的影响。例如,选择“R13”(REX.B = 1, r/m = 101B)时,只要mod = 00B仍然会导致rip相对寻址。REX.B结合ModR/ m的4位r/m字段没有被完全解码。为了处理没有位移的R13,软件必须使用1字节的位移0对R13 + 0进行编码。
rip相对寻址由64位模式启用,而不是64位的address-size。使用address-size前缀不会禁用rip相对寻址。地址大小前缀的作用是截断并零扩展计算出的有效地址为32位。