Linux內核0.12——內核編程語言和環境

/********AT&T 彙編格式********/

1、爲了維持與gcc輸出彙編程序的兼容性,as彙編器使用AT&T系統V的彙編語法,這裏主要說明一下它與intel彙編的語法區別

2、AT&T與intel彙編語法格式的區別
1)寄存器引用:mov %eax,%ebx
2)操作數順序:mov %eax(源),%ebx(目的)
3)立即數格式:mov $4,%ebx(如果不加$,則認爲4是地址);mov value,%ebx(可以直接引用符號常數);mov $value,%ebx(引用了符號常數作爲地址)
4)操作數長度:movb %eax,%ebx(movb爲mov byte ptr,movw爲mov word ptr,movl爲mov long ptr)

5)跳轉指令:ljmp $section,$offset;lcall $section,$offset;lret $stack_adjust(等同於intel彙編格式的:jmp far section:offset;call far section:offset;ret far stack_adjust)

6)內存引用:section:[base + index*scale + disp](等同於intel彙編:section:disp(base,index,scale))

/*********嵌入彙編********/

1、C程序的產生過程(gcc編譯器):.c源文件----(cpp預處理)---->.c純C----(cc編譯器)---->.s彙編程序----(as彙編器)---->.o目標文件----(.a庫文件+ld連接器)---->可執行文件

2、嵌入彙編格式:

__asm__("assemble language"
:output register
:input register
:to be changed register);
說明:1、爲了讓gcc編譯產生的彙編程序中寄存器前面有一個%,在嵌入彙編語句中寄存器名稱前需加兩個%;2、輸出寄存器格式爲"=a"(__res),這是指將eax的值輸出到__res變量中去,具體的Google。。。3、在前幾個寄存器中已經包括了要被改變的寄存器的時候,就不要在要被改變的寄存器一項添加了

簡單的strcpy函數代碼:

char * strcpy(char * dest,const char * src)
{
__asm__("cld\n"
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
::"S"(src),"D"(dest));
return dest;
}
3、C函數調用機制:“設置”,初始化棧幀結構;“主體”,執行函數的實際計算操作;“結束”,恢復棧狀態並從函數中返回

4、C和彙編的互相調用:

在彙編中調用C:比較自由,只要是在棧中適當位置的內容就都可以作爲參數供C函數使用;我們可以不用CALL指令而採用JMP指令來達到調用函數的目的

在C中調用匯編:方法和前者一樣,重點仍然是對函數參數在棧中位置的確定上

/******目標文件格式及其鏈接*******/

1、目標文件組成(具體參見include/a.out.h文件):

依次序總的爲:a.out文件頭、代碼部分、數據部分、代碼重定位信息、數據重定位信息、符號表和字符串表

執行頭部分:1)魔數字段值:0x107魔數OMAGIC指明文件是目標文件或者是不純的可執行文件;0x10b魔數ZMAGIC指明文件爲需求分頁處理的可執行文件;2)a_text、a_data和a_bss分別指明後面只讀的代碼段、可讀寫的數據段和數據段後面未初始化數據區域的長度;3)a_entry指明瞭程序代碼開始執行的地址;4)a_syms、a_trsize和a_drsize分別指明瞭數據段後面符號表、代碼和數據段重定位信息的大小。

重定位信息部分:重定位信息爲struct relocation_info{..}結構體;在代碼段被重定位到不同的基地址處時,重定位項指出需要修改的地方;在模塊文件中存在對未定義符號引用時,當此未定義符號最終被定義時連接程序就可以使用相應重定位項對符號值進行修改。

符號表和字符串部分:這是目標文件的最後部分;符號表記錄項需要記錄該符號的符號名、符號名字符串在字符串表中的偏移位置、符號的類型、是否爲全局的、符號的值

2、查看目標文件中的具體值:

objdump -h hello.o
查看可執行文件的具體值:

objdump -h hello
3、鏈接程序的任務

1)給執行文件進行存儲空間分配操作。一旦存儲位置確定,鏈接程序就可以繼續執行符號綁定操作和代碼修正操作

2)把所有模塊中相同類型的段組合連接在一起,在輸出文件中爲指定段類型形成單一一個段

4、內核加載可執行文件

1)首先,內核根據文件頭部結構中的信息首先判斷文件是不是一個合適的可執行文件

2)然後系統在用戶態堆棧頂部爲程序設置環境參數和命令行上輸入的參數信息塊併爲其構建一個任務數據結構

3)接着在設置了一些相關寄存器值後利用堆棧返回技術去執行程序。執行程序映像文件的代碼和數據將會在實際執行到或用到時利用需求加載技術動態加載到內存中

/*****makefile*****/

參見:http://blog.csdn.net/fengxiaoke_fxk/article/details/7525804


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章