1.馮諾依曼體繫結構(存儲程式電腦) 1.1 解釋 從硬體角度可以抽象為一下模型: 從硬體角度可以抽象為一下模型: CPU與記憶體通過匯流排連接,CPU中有很多寄存器(總是指向記憶體的某一塊區域),如IP(Instruction Pointer)。假如指向CS(Code Segment,代碼段),CPU ...
1.馮諾依曼體繫結構(存儲程式電腦)
1.1 解釋
-
從硬體角度可以抽象為一下模型:
CPU與記憶體通過匯流排連接,CPU中有很多寄存器(總是指向記憶體的某一塊區域),如IP(Instruction Pointer)。假如指向CS(Code Segment,代碼段),CPU從IP指向的記憶體的地址,取指令執行,執行過後IP自加1,取下一條指令,重覆上述步驟。
-
從程式員的角度可以抽象為一下模型:
CPU不斷執行next instruction,從記憶體取指令不斷執行。
記憶體保存數據和指令,CPU負責解釋和執行指令。
1.2 API和ABI
cpu識別什麼指令,怎麼定義?
API:程式員與電腦的介面界面
ABI:程式與CPU的介面界面
2.×86寄存器
2.1 通用寄存器
2.2 段寄存器
CPU在實際取指令是根據cs:eip來確定一個指令
3.×86彙編指令
指令 |
含義 |
模式/模型 |
movl %eax,%edx |
edx=eax |
register mode,以%開頭的寄存器標示符 |
movl $0x123,%edx |
edx=0x12 |
immediate,立即數以$開頭的數值 |
movl 0x123(沒有$符表示地址),%edx |
edx=*(int32_t*)0x123 |
direct,直接訪問一個指定的記憶體地址的數據 |
movl (%ebx)(ebx寄存器存的值——記憶體地址,加括弧表示記憶體地址存的數據放在ebx),%edx |
edx=*(int32_t*)ebx |
indirect,將寄存器的值作為一個記憶體地址來範圍記憶體 |
movl 4(%ebx),%edx |
edx=*(int32_t*)(ebx+4) |
displaced,在間接定址時改變寄存器的值 |
pushl %eax |
subl $4,%esp |
|
popl %eax |
movl(%esp),%eax |
|
call 0x12345(調用0x12345地址) |
pushl %eip(*)(當前的eip壓棧) |
|
ret |
popl %eip(*) |
|
enter |
pushl %ebp |
|
leave |
movl %ebp,%esp |
b,w,l,q分別代表8位,16位,32位,64位
eip指向記憶體的指令,自加一(一條指令),*代表這些指令不能被程式員直接使用,程式不能直接修改eip寄存器
4.彙編代碼分析
1 #include <stdio.h> 2 3 int g(int x) 4 5 { 6 7 return x + 3; 8 9 } 10 11 12 13 int f(int x) 14 15 { 16 17 return g(x); 18 19 } 20 21 22 23 int main(void) 24 25 { 26 27 return f(8) + 1; 28 29 }
gcc -S -o main.s main.c -m32,對應的彙編代碼
1 g: 2 3 pushl %ebp 4 5 movl %esp, %ebp 6 7 movl 8(%ebp), %eax 8 9 addl $3, %eax 10 11 popl %ebp 12 13 ret 14 15 f: 16 17 pushl %ebp 18 19 movl %esp, %ebp 20 21 subl $4, %esp 22 23 movl 8(%ebp), %eax 24 25 movl %eax, (%esp) 26 27 call g 28 29 leave 30 31 ret 32 33 main: 34 35 pushl %ebp 36 37 movl %esp, %ebp 38 39 subl $4, %esp 40 41 movl $8, (%esp) 42 43 call f 44 45 addl $1, %eax 46 47 leave 48 49 ret
動畫演示: