#x64匯編第二講,復習x86匯編指令格式,學習x64指令格式
目錄
- x64匯編第二講,復習x86匯編指令格式,學習x64指令格式
- 一丶x86指令復習.
- 1.1什麽是x86指令.
- 1.2 x86與x64下的通用寄存器
- 1.3 OpCode
- 1.4 7種尋址方式
- 二丶x86指令格式詳解.
- 2.1 instruction 說明
- 2.2 Opcode
- 2.3 ModR/m說明
- 2.4 SIB說明
- 2.5 Displacement 偏移說明
- 2.6 immediate 立即數
- 二丶X64 匯編指令格式詳解
- 一丶x86指令復習.
x64匯編第二講,復習x86匯編指令格式,學習x64指令格式
一丶x86指令復習.
1.1什麽是x86指令.
代碼如下.
高級代碼為:
int i = 0;
int *p - &i;
此時產生了3條匯編指令
mov dword ptr[i],0 OPCODE = C7 45 F4 00 00 00 00
lea eax,[i]
mov dword ptr [p],ea OPCODE = 89 45 E8
此時觀察,有兩條 Mov
1.2 x86與x64下的通用寄存器
在x86下面,我們的通用寄存器有
eax ebx ecx edx esi edi esp ebp [e 代表 Extend(擴展)]
在x64下面,新加了幾個寄存器.並且指令變大了 有16個通用寄存器
rax rbx rcx rdx rsi rdi rsp rbp
r8 r9 r10 r11 r12 r13 r14 15
在x86下,我們的寄存器都有自己的編號.
指令 | 編號 |
---|---|
eax | 000 |
ecx | 001 |
edx | 010 |
ebx | 011 |
esp | 100 |
ebp | 101 |
esi | 110 |
edi | 111 |
1.3 OpCode
每個指令都有一個或者多個編碼.
如下常見的
指令 | OpCode | 說明 |
---|---|---|
ret | 0xC3 | 返回 |
short jump | 0xEB | 短跳轉 8位 |
far jump | 0xEA | 長跳轉,可以在4GB空間任意跳轉 32位 |
je/jz | 0x74 | 判斷是否相等 |
jne/jnz | 0x75 | 判斷是否不等 |
nop | 0x90 | 空指令 |
1.4 7種尋址方式
尋址方式 | 尋址代碼 |
---|---|
立即數尋址 | mov eax,1 |
寄存器尋址 | mov eax,ebx |
直接尋址 | mov eax,[2000h] |
寄存器間接尋址 | mov eax,[ebx] |
寄存器相對尋址 | mov eax[ebx + 0x100] |
基址變址尋址 | mov eax,[ebx + esi] |
相對基址變址尋址 | mov eax,[ebx + esi *n] |
二丶x86指令格式詳解.
在X86下,查看inter手冊可以清楚的看到x86匯編的指令格式.
圖標如下
x64的圖表
以x86為例,有6個部分. 只有Opcode時必須的.前邊的可以沒有
2.1 instruction 說明
instruction prefixes 指令前綴. 如 rep movs bytes ptr[esi]
rep 就是前綴.
2.2 Opcode
Opcode 這個需要查看inter手冊.
如下:
2.3 ModR/m說明
ModR/m
裏面分為三部分
指令 | 說明 |
---|---|
Mod | 表示寄存器的尋址方式. |
Reg/opcode | 表示寄存器或者OpCode的編碼 |
R/M | 表示匯編中第一個寄存器的編碼. |
Mod 代表尋址方式 2位表示
指令 | 說明 |
---|---|
00 | 寄存器間接尋址 |
01 | 寄存器相對尋址偏移 |
10 | 寄存器先對尋址偏移 |
11 | 寄存器直接尋址 |
其它尋址方式放在SIB裏面
Reg/Opcode 代表指令,
如 mov [ebp - 38h],eax. 那麽就代表eax的編號
有時候表示寄存器,有時候表示Opcode
R/M 表示匯編的第一個寄存器
如 mov[ebp - 38h],eax 代表的是ebp
2.4 SIB說明
SIB 占一個字節.可能有可能沒有,是對ModR/M尋址的補充.
一條匯編指令
mov eax,[ebx + edi * 4 + 1000h]
根據匯編指令我們可以得出:
偏移 = 1000h
倍率 = 4
基址 = ebx
那麽根據上面我們的SIB解析就好辦了
名稱 | 大小 | 說明 |
---|---|---|
scale | 2 bit | 表示倍率,如上面edi *4 4就是倍率,只能是1 2 4 8 ,00代表倍率為1,01=2 10 = 4 11 = 8 |
index | 3 bit | 表示倍率前邊的寄存器 如edx * 4,那麽edi的編號就放在這裏 |
base | 3 bit |
那麽根木上面說明我們可以拆分如下.
scale | index | base |
---|---|---|
4 | edi | ebx |
2.5 Displacement 偏移說明
Displacement 其實是一個偏移
如:
mov eax,[ebx + edi * 4 + 1000h]
1000h就是偏移,會放在這個字段當中.
可以是1個字節,可以是2個字節,或者4個字節.
2.6 immediate 立即數
immediate 是立即數
如:
mov eax,1
在32位中占 1 2 4個字節.
其中講到這大概說明白了. 除了Opcode不能省略.其余都是可選的.
在32位指令最長可以支持17個字節.
二丶X64 匯編指令格式詳解
x86圖表
x64的圖表
在x64下,只對 x86加了一個 REX (re Extend 在擴展)
REX是一個字節.但是高4位必須為0100
REX取值範圍在40-4F之間.
低四位有不同的含義,這是inter手冊拿下來的
W (width)
如果為0 代表這個指令是32位的
如果為1 則代表指令是64位的.
R位
R主要是對32位下 MOdR/M中的 Reg/Opcode做了擴充.
以前是3位,現在是4位來表示了.
因為為了兼容32位.所以32位的表不能動.所以只能在這繼續進行擴充.
X(index}
這個主要是擴充 SIB 中的index位的.
32位下 Index代表 倍率的寄存器.如 edi * 4 4是倍率. edi則是
倍率寄存器.在32位下這個是3位.只能表示一個寄存器
64下需要對它進行擴種.就是x index.
B(base)
這個主要是擴充 32位下 Modr/M 中的 R/M位. 或者 SIB中 Base基址位.
例子:
如:
mov eax,2
Opcode = b8 10 0 00 00
那麽擴展為64位的就是
48 b8 10 00 00 00 00 00 00 00
48的意思就是 0100 1000
就是說 在w 位設置為1,代表的是64位匯編指令.
#x64匯編第二講,復習x86匯編指令格式,學習x64指令格式