表白:黑白圣堂血天使,天劍鬼刀阿修羅。
講解對(duì)象:/CPU 指令
作者:融水公子 rsgz
匯編教程匯編教程 http://www.rsgz.top/post/91.html
我們通過(guò)函數(shù)來(lái)理解一下。下面是一個(gè)簡(jiǎn)單的函數(shù)int add_a_and_b(int a, int b) { return a + b; } int main() { return add_a_and_b(2, 3); }
gcc編譯器可以將這個(gè)程序轉(zhuǎn)化成匯編語(yǔ)言。發(fā)現(xiàn)轉(zhuǎn)換之后的匯編語(yǔ)言就是一行行的指令,CPU只要執(zhí)行這一行行的指令就可以完成函數(shù)的操作了,匯編會(huì)用標(biāo)簽add_a_and_b和main代替兩個(gè)函數(shù)_add_a_and_b: push %ebx mov %eax, [%esp+8] mov %ebx, [%esp+12] add %eax, %ebx pop %ebx ret _main: push 3 push 2 call _add_a_and_b add %esp, 8 ret分析:執(zhí)行的順序是這樣的。_main: //棧為_(kāi)main建立一個(gè)幀,地址寫(xiě)入ESP 寄存器 push 3 //ESP 寄存器減去整型3的四個(gè)字節(jié),push指令把3放入main幀里面 push 2 //ESP 寄存器減去整型2的四個(gè)字節(jié),push指令把2放入main幀里面 累積減了8字節(jié) call _add_a_and_b //call指令用來(lái)調(diào)用函數(shù),建立add_a_and_b幀 -------------------------------------------------------------- _add_a_and_b: //棧為add_a_and_b建立一個(gè)幀,地址寫(xiě)入ESP 寄存器 push %ebx //ESP 寄存器減去四字節(jié),EBX 寄存器里面的值,寫(xiě)入_add_a_and_b這個(gè)幀 ,累計(jì)減去12字節(jié) mov %eax, [%esp+8] //ESP 寄存器里面地址加8字節(jié),對(duì)應(yīng)的是2,將2寫(xiě)入 EAX 寄存器 mov %ebx, [%esp+12] //ESP 寄存器里面地址加12字節(jié),對(duì)應(yīng)的是3,將3寫(xiě)入 EBX 寄存器 add %eax, %ebx //兩個(gè)運(yùn)算子相加,并將結(jié)果寫(xiě)入第一個(gè)運(yùn)算子 pop %ebx //ESP 寄存器里面地址加4字節(jié),加法已經(jīng)做完了,EBX 寄存器用不到了 ret //ret指令終止當(dāng)前函數(shù)的執(zhí)行,當(dāng)前函數(shù)的幀將被回收 -------------------------------------------------------------- add %esp, 8 // ESP 寄存器地址手動(dòng)加8個(gè)字節(jié),等于說(shuō)之前的12字節(jié)都收回來(lái)了 ret //ret指令退出main函數(shù)最后我繼續(xù)畫(huà)一個(gè)畫(huà)畫(huà)吧
===
公眾號(hào):小雪妃謝謝大家的支持!可以點(diǎn)擊我的頭像,進(jìn)入我的空間瀏覽更多文章呢。建議大家360doc[www.360doc.com]注冊(cè)一個(gè)賬號(hào)登錄,里面真的有很多優(yōu)秀的文章,歡迎大家的到來(lái)。
---
聯(lián)系客服