一,、匯編基礎(chǔ)
1 .section .data 2 .section .text 3 .globl _start 4 _start: 5 6 7 匯編中,,以點(diǎn)(.)開頭的名稱不會(huì)被翻譯成機(jī)器指令,而是給匯編器的一些特殊指令,,稱為匯編指示(assembler directive)或偽操作(pseudo-operation). 1. .section .data .section指示把代碼劃分為若干段(section),程序被操作系統(tǒng)加載執(zhí)行時(shí),,每個(gè)段被加載到不同的地址,,具有不同的讀、寫,、執(zhí)行權(quán)限. .data段保存程序的數(shù)據(jù),,是可讀可寫的。C程序的全局變量也屬于.data段,。如果沒有定義數(shù)據(jù),,.data段可為空。 2. .section .text .text段保存代碼,,是只讀和可執(zhí)行的,,后面那些指令都屬于這個(gè).text段。 3 .globl _start .globl告訴匯編器,,_start這個(gè)符號(hào)要被鏈接器用到,,所以在目標(biāo)文件的符號(hào)表中要特殊標(biāo)記。_start就像C程序的main一樣特殊,,是程序的入口地址,。每個(gè)匯編程序都要提供一個(gè)_start符號(hào)并用.globl聲明。 _start是個(gè)符號(hào)(symbol).符號(hào)在匯編中代表一個(gè)地址,,在指令中,,所有的符號(hào)都被替換成它所代表的地址值。 4 _start: 在匯編中,立即數(shù)前面加$,,寄存器名前加%,以便跟符號(hào)區(qū)別開,。 int指令為軟中斷指令,,可以用這條指令故意產(chǎn)生一個(gè)異常。異常處理和中斷類似,,CPU從用戶模式切換到特權(quán)模式,,然后跳轉(zhuǎn)到內(nèi)核代碼中執(zhí)行異常處理程序。內(nèi)核提供了很多系統(tǒng)服務(wù)供用戶程序使用,,這些系統(tǒng)服務(wù)不能像庫函數(shù)那樣調(diào)用,,因?yàn)閳?zhí)行用戶程序時(shí)CPU處于用戶模式,不能調(diào)用內(nèi)核函數(shù),,所以要通過系統(tǒng)調(diào)用切換CPU模式,,通過異常處理程序進(jìn)入內(nèi)核,而不能由用戶程序隨心所欲,,想調(diào)哪個(gè)內(nèi)核函數(shù)就調(diào)哪個(gè)內(nèi)核函數(shù),,這樣保證系統(tǒng)服務(wù)被安全調(diào)用,。在調(diào)用結(jié)束后,CPU再切換到用戶模式,,繼續(xù)執(zhí)行int指令后面的指令,,在用戶程序看來就跟函數(shù)調(diào)用和返回一樣。eax和ebx寄存器的值是傳遞給系統(tǒng)調(diào)用的兩個(gè)參數(shù),,eax的值是系統(tǒng)調(diào)用號(hào),,1表示_exit系統(tǒng)調(diào)用。ebx值則是個(gè)_exit系統(tǒng)調(diào)用的參數(shù),,即退出狀態(tài),。 Little Endian Big Endian 二,、C內(nèi)聯(lián)匯編 "r"(a)指示編譯器分配一個(gè)寄存器保存變量a的值,作為匯編指令的輸入,,也就是指令中的%1(按照約束條件的順序,,b對(duì)應(yīng)%0,a對(duì)應(yīng)1%),,至于%1究竟代表哪個(gè)寄存器則由編譯器自己決定,。匯編指令首先把%1所代表的寄存器的值傳給eax(為了和%1這種占位符區(qū)分,eax前面要求加兩個(gè)%號(hào)),,然后把eax的值再傳給%0所代表的寄存器,。"=r"(b)就表示把%0所代表的寄存器的值輸出給變量b。在執(zhí)行這兩條指令的過程中,,寄存器eax的值被改變了,,所以把"%eax"寫在第四部分,告訴編譯器在執(zhí)行這條__asm__語句時(shí)eax要被改寫,,所以在此期間不要用eax保存其它值,。 |
|