_start是匯程式設計序的入口,main是c程式的入口?
gcc 只是乙個 外殼而不是真正的編譯器,這真的c編譯器是/usr/lib/gcc/i486-gun/4.3.2/cc1,gcc呼叫c編譯器、彙編器和鏈結器完成c **的編譯鏈結工作。/usr/lib/gcc/i486-linux-gun/4.3.2/collect2是鏈結器ld的外殼,它呼叫ld完成鏈結。
i main.c被cc1編譯成匯程式設計序/tmp/ccrgdpua.s。
ii 這個匯程式設計序被as彙編成目標檔案/tmp/ccidnz1d.o
iii 這個目標檔案連同另外幾個目標檔案(crt1.o,crti.o,crtbegin.o,crtend.o,crtn.o)一起鏈結成可執行檔案 main。在鏈結過程中還用-l,選項指定一些庫檔案,有libc、libgcc、ligcc_s,其中有些庫是共享庫,需要動態鏈結,所以用 -dynamic-linker選項指定動態鏈結器是/lib/ld-linux.so.2
$ nm /usr/lib/crt1.o
00000000 r _io_stdin_used
00000000 d __data_start
u __libc_csu_fini
u __libc_csu_init
u __libc_start_main
00000000 r _fp_hw
00000000 t _start
00000000 w data_start
u main
u main 這一行表示main這個符號在crt1.o已經被引用了,但是還沒有定義(undefined),因此需要別的目標檔案提供乙個定義並且和crt1.o鏈結在一起。t_start表示在crt1.o中已定義為(text)。
c 程式的入口點其實是crt1.o提供的_start,它先做一些初始化工作(啟動例程,startup routine),然後呼叫我們編寫的main函式。所以,main函式是程式的入口,不夠準確。_start才是真正的入口點,而main函式是被 _start呼叫的。
i 作業系統在載入main這個程式時,首先看它有沒有需要動態鏈結的未定義符號。
ii如果需要做動態鏈結,就檢視這個程式指定了哪些共享庫,以及用什麼動態鏈結器來做動態鏈結。我們在鏈結時用-lc選項指定了共享庫libc,用-dynamic-linker /lib/ld-linux.so.2 指定動態鏈結器,這些資訊都會寫到可執行檔案中。
iii動態聯結器載入共享庫,在其中查詢這些未定義符號的定義,完成鏈結過程。
c內聯彙編
完整的內聯彙編格式:
__asm__(asembler template
:output operands
: input operands
: list of clobbered registers
e.g.
#include
int main(void)
int a=10,b;
__asm__("movl %1,%%eax\n\t"
"movl %%eax,%0\n\t"
:"=r"(b) //把%0所代表的暫存器的值輸出給變數b
:"r"(a) //告訴編譯器分配乙個暫存器儲存變數a的值,作為匯程式設計序的輸入,對應%1
:"%eax"
printf("result:%d,%d\n",a,b);
return 0;
彙編與C的基本邏輯語句對應關係
基本函式結構 push ebp mov ebp,esp sub esp,44h push ebx push esi push edi lea edi,ebp 44h mov ecx,11h mov eax,0cccccccch rep stos dword ptr edi xor eax,eax 若...
彙編與C語言關係 3 變數的儲存布局
以下面c程式為例 include const int a 10 int a 20 static int b 30 int c int main void 我們在全域性作用域和main函式的區域性作用域各定義了一些變數,並且引入一些新的關鍵字const,static,register來修飾變數,那麼這...
彙編與C互操作
彙編與c互操作 c語言內嵌彙編 c語言呼叫彙編過程 彙編呼叫c語言過程 1 開啟vs2008,建立乙個vc 空工程。2 在solution explorer上右擊工程名,選擇custom build rules 在彈出的對話方塊上勾選microsoft macro assembler。3 在solu...