彙編的分類
8086彙編(16bit)
x86彙編(32bit)
x64彙編(64bit)
ARM彙編(嵌入式、移動設備)
…
彙編語言不區分大小寫
x64彙編根據編譯器的不同,有2種書寫格式:Intel 和 AT&T
Intel 和 AT&T的區別
寄存器
寄存器就是用來存放運算結果的硬件,把內存裏的樹調入寄存器,經過cpu運算後,再放入寄存器,最後再調入內存
這是因爲有些彙編指令只能對寄存器操作,不能直接對內存操作,這是由cpu架構決定的
比如mov指令不能直接從內存賦值到內存,必須藉助寄存器
不同編譯器寄存器不同
R開頭的寄存器是bit,佔8字節;E開頭的寄存器是32bit,佔4字節;
x86彙編寄存器
彙編指令
要在編譯器中debug模式下調試,在release下編譯器會優化
mov
mov dest, src將src的內容賦值給dest,類似於dest = src
◼ [ 地址值 ],括號[ ]裏面放的都是內存地址
◼ word是2字節,dword是4字節(double word),qword是8字節(quad word)
在彙編下查看
a的內存地址就是EBP-C,不知道爲什麼,這編譯器沒有顯示
在彙編頁面右擊只顯示源代碼,就能看到
調試的時候你會發現每一次調試,a的值都會發生變化,這是因爲a是個局部變量,每次調用main這個局部函數,都會在內存中創建一個棧,分配空間,用完後銷燬,而每一次分配的內存並不一定是同一塊區域(即每次EBP是不一樣的)。
放在外面就是全部變量,每次打開輸出a的地址都是一樣的。
call
f11跳轉到指定位置
lea(load effect address)
lea dest, [ 1111H ]
將地址值賦值給dest,類似於dest = 地址值
ret
函數返回
xor op1, op2
將op1和op2異或的結果賦值給op1,類似於op1 = op1 ^ op2
add op1, op2
類似於op1 = op1 + op2
sub op1, op2
類似於op1 = op1 - op2
inc op
自增,類似於op = op + 1
dec op
自減,類似於op = op – 1
jmp 內存地址
跳轉到某個內存地址去執行代碼
開頭的一般都是跳轉,大多數是帶條件的跳轉,一般跟test、cmp等指令配合使用
int a = 3;
mov dword ptr [ebp-8],3
int b = 4;
mov dword ptr [ebp-14h],4
if (a > b) {
mov eax,dword ptr [ebp-8]
cmp eax,dword ptr [ebp-14h]
jle 008D2057
a = 1;
mov dword ptr [ebp-8],1
}else {
jmp 008D205E
b = 1;
mov dword ptr [ebp-14h],1
}
getchar();
mov esi,esp
call dword ptr ds:[008DA194h]
cmp esi,esp
call 008D1226
return 0;
xor eax,eax
}