【VIP专享】64位汇编语言简介

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

x86-64位汇编语言简介

一、x86-64的寄存器

x86-64较x86-32多了8个通用寄存器,而且,每个通用寄存器都是64位宽,它们是:

rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp

r8,r9,r10,r11,r12,r13,r14,r15

同时,x86-64全面支持x86-32和x86-16的通用寄存器:

eax,ax,al,ah,

ebx,bx,bl,bh,

....

而且,还对传统的edi,esi做了改进:

edi ,32位

di,16位

dil ,8位,在传统的x86机器中,di是不可按照8位来访问的,但在x86-64下可以。

同样esi也可以按照8位来访问。一个很特别的寄存器rip,相当于x86-32的eip. 在x86-32是不可直接访问的,如mov eax,eip是错的,但在x86-64位下却可以,如mov,rax,qword ptr [rip+100]是对的。而且,它除了是个程序计数器外,也是个“数据基地址”,有此可见,它现在是身兼两职!为什么在x86-64位下要用rip做访问数据的基地址呢?因为,在x86-64下,DS,ES,CS,SS都没有实际意义了,也就是说,它们不再参与地址计算,

只是为了兼容x86-32。FS,GS还是参与地址计算,它们两个和x86-32的意义相同。

二、x86-64的汇编

x86-64的汇编和x86-32的没有多大的区别。添加了新寄存器和指令。

写64位汇编代码时,可以用8、16、32、64位寄存器,如:

push rdi

sub rsp, 48 ;

mov r10, rcx

; Line 36

mov rdi, rdx

xor eax, eax

mov ecx, 512

rep stosb

; Line 43

movsxd r8, DWORD PTR [r10+16]

mov QWORD PTR [rsp+32], rdx

mov r9, QWORD PTR [r10+648]

mov rdx, QWORD PTR [r10+52]

mov rcx, QWORD PTR [r10+44]

call fs_read_disk

; Line 47

mov ecx, 1

cmp eax, ecx

cmovne ecx, eax

mov eax, ecx

; Line 52

add rsp, 48

pop rdi

ret 0

再如:

$L1818:

; Line 2398

mov al, BYTE PTR [rdx+rbx]

cmp al, 32

jne SHORT $L1819

mov BYTE PTR [rdx+rbx], 0

$L1819:

add r8d, 1

movsxd rdx, r8d

xor eax, eax

mov rcx, r12

mov rdi, rbx

repne scasb

not rcx

sub rcx, 1

cmp rdx, rcx

jb SHORT $L1818

但,有点值得注意,当操作传统的32位寄存器时,那么,整个64位寄存器都会受到影响,如:

mov eax,0ah

那么,rax也等于000000000000000ah

再如:

mov rcx,0aaaaaaaaaaaaaaaah

(此时ecx等于0aaaaaaaah)

mov ecx,0ddddddddh

(此时,rcx等于00000000ddddddddh,高32位受到了影响).

规则:

Example 1: 64-bit Add:

Before:RAX =0002_0001_8000_2201

RBX =0002_0002_0123_3301

ADD RBX,RAX ;48 is a REX prefix for size.

Result:RBX = 0004_0003_8123_5502

Example 2: 32-bit Add:

Before:RAX = 0002_0001_8000_2201

RBX = 0002_0002_0123_3301

ADD EBX,EAX ;32-bit add

Result:RBX = 0000_0000_8123_5502

(32-bit result is zero extended)

Example 3: 16-bit Add:

Before:RAX = 0002_0001_8000_2201

RBX = 0002_0002_0123_3301

ADD BX,AX ;66 is 16-bit size override

Result:RBX = 0002_0002_0123_5502

(bits 63:16 are preserved)

Example 4: 8-bit Add:

Before:RAX = 0002_0001_8000_2201

RBX = 0002_0002_0123_3301

ADD BL,AL ;8-bit add

Result:RBX = 0002_0002_0123_3302

(bits 63:08 are preserved)

三、指令集变化小结:

当然,这里说的都是最基本的东西,是针对通用寄存器言的。其实,x86-64对FPU(数学处理单元)和MMX,SSE,SSE2都做了很大的改进。然而,对写OS来说,我们最关心的还是通用寄存器

1.地址宽度和操作数宽度前缀

64位模式中,缺省的地址宽度是64位,缺省的操作数宽度是32位。地址宽度和操作数宽度前缀允许32位和64位数据和地址在指令序列中混用。下表(1-7)显示了在IA-32e模式下需要指令前缀地址宽度。注意,在64位模式下不支持16位地址。在敬爱内容和传统模式下,地址宽度函数的功能和在IA-32传动架构中一样。

下表(1-8)显示了66H指令前缀和REX.W前缀的有效组合来指定IA-32e操作模式下的操作数宽度问题。

在64位模式下,缺省的操作数宽度是32位,REX前缀包括4位域来指定16个不同的值。REX前缀的W位域指定为REX.W。REX.W=1时前缀表明操作数位64为操作数。注意,软件依然能使用操作数宽度66H前缀来切换到16位操作宽度。然而如果同时用REX.W和66H前缀,REX.W的优先权要高。

在SSE/SSE2/SSE3 SIMD指令的情况下,66H, F2H和F3H前缀作为操作码扩展,并被认为是指令的一部分。在这些情况下,有效的REX.W前缀和66H代码扩展前缀之间没有相互关系。

2.REX前缀

REX前缀是64位模式下引入的新的指令前缀字节,他作以下工作:

•指定新的GPRs和SSE寄存器

相关文档
最新文档