馮諾依曼體系結構
核心思想
1.馮諾依曼是:數字計算機的數制采用二進制;計算機應該按照程序順序執行。
2.采用二進制作為計算機數值計算的基礎,以0、1代表數值。不采用人類常用的十進制計數方法,二進制使得計算機容易實現數值的計算。
3.程序或指令的順序執行,即預先編好程序,然后交給計算機按照程序中預先定義好的順序進行數值計算。
匯編語言的五種尋址模式
·????????寄存器尋址 registermode:?%寄存器 ?例如:%edx 訪問寄存器edx
·????????立即尋址 immediate:?$數字?? 例如:$0x123 數值0x123
·????????直接尋址 direct:數字???例如:0x123訪問地址0x123指向的內存
·????????間接尋址 indirect:?(%寄存器)?(%ebx) 例如:訪問寄存器ebx中的地址指向的內存
·????????變址尋址 displaced:偏移量(%寄存器)?4(%ebx):訪問寄存器ebx中的地址再加4指向的內存;
幾個重要的匯編指令
Example instruction | What it does |
Pushl %eax | Subl $4, %esp?? //棧頂指針減4,棧在向下生長一個位置 Movl %eax, (%esp) //將eax中的值放入棧頂指針指向的內存位置 |
Popl %eax | Movl (%esp), %eax //從棧頂指針指向的內存中的值放入eax中 Addl $4, %esp //棧頂指針加4,棧在向上收縮 |
Call 0x12345 | Pushl %eip //ip壓棧 Movl $0x12345, %eip //將0x12345放入eip中 |
Ret | Popl %eip //ip出棧 |
?
使用gcc -S -o main.s main.c -m32命令將源代碼編譯成匯編代碼。
源代碼如下:
int g(int x) { return x + 9; } int f(int x) { return g(x); } int main(void) { return f(18) + 11; }
編譯后的代碼如下:
g:pushl %ebpmovl %esp, %ebpmovl 8(%ebp), %eaxaddl $9, %eaxpopl %ebpretf:pushl %ebpmovl %esp, %ebpsubl $4, %espmovl 8(%ebp), %eaxmovl %eax, (%esp)call gleaveretmain:pushl %ebpmovl %esp, %ebpsubl $4, %espmovl $18, (%esp)call faddl $11, %eaxleaveret
堆棧變化過程
1.main函數--pushl %ebp + movl %esp,%ebp
2.main函數--subl $4,%esp + movl $18,(%esp)
3.main函數--call f
4.f函數--pushl %ebp + movl %esp,%ebp
5.f函數--subl $4,%esp + movl 8(%ebp),%eax + movl %eax, (%esp)
6.f函數--call g
7.g函數--pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %eax
8.g函數--addl $9,%eax + popl %ebp
9.g函數--ret 下一步將運行第15行的指令也就是f函數的leave指令
10.f函數--leave
11.f函數--ret 下一步將運行第23行的指令也就是main函數的addl指令
實驗截圖
?
黃偉業原創作品轉載請注明出處《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000