1. 程式人生 > >#x64匯編第二講,復習x86匯編指令格式,學習x64指令格式

#x64匯編第二講,復習x86匯編指令格式,學習x64指令格式

字段 空間 9.png tle 機器 class ptr scale 進行

目錄

  • 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 匯編指令格式詳解

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指令格式