摘要:最開始的第一句CALL0003是我們用nasm編譯的start.asm所生成的代碼。我們主要目標是研究藍色的C語言的代碼,第一句start.asm所生成的代碼太簡單,就是調用e_main函數。而我們的e_main函數就是藍色代碼部分。從C源程序中我們看到,我們在e_main做的就是一件事情:調用e_putchar(ch);其中ch是傳給出e_putchar的參數。MOVAX,000
我們主要目標是研究藍色的C語言的代碼,第一句start.asm所生成的代碼太簡單,就是調用e_main函數。而我們的e_main函數就是藍色代碼部分。
從C源程序中我們看到,我們在e_main做的就是一件事情:調用e_putchar(ch);其中ch是傳給出e_putchar的參數。
MOV AX,000B
000B就是我們的全局變量ch所在內存的地址。C語言會把所有的全局變量在另一塊內存區.C代碼先把ch的地址傳給AX,然后通過
PUSH AX
把AX的值,也就是ch的地址壓入堆棧。然后再
CALL 0020
而0020就是e_putchar代碼的地址。通過這跳語句,計算機就跳到e_putchar的代碼部分去執行了.我在這里并不給出e_putchar的代碼,因為我們這個案例只是研究C語言中如何傳遞參數給其它函數的,并不管e_putchar如何取參數。下在一個案例中,我們將研究函數如何取參數。
在這里我得把CALL指令解釋清楚,因為在下個研究函數如何取參數的部分中大家可能會迷惑.CALL XXXX 指令簡單地或就是
PUSH IP
JMP XXXX
它首先把當前的執行地址IP壓入堆棧,然后跳轉到要CALL的地址去。CALL和RET指令是配套的。RET指令等同于
POP IP
也就是回復CALL前的執行地址IP。
正因為這樣,所以你一旦使用了CALL指令,你的堆棧指針SP就會自動減2。
POP CX
是每個函數調用完畢后都有的常用操作。在這里它不起任何作用。可能作用就是與CALL 0020前的PUSH AX像對應.這樣堆棧指針SP才能回原。
好了,簡單的第一個案例研究結束了。雖然就這4跳指令,但是我們已經可以看出C語言傳遞參數方法了。總結起來就是通過"MOV AX,參數地址"把參數的地址傳到AX,然后"PUSH AX"把參數的地址壓入堆棧。最后"CALL 函數地址"轉向執行要調用的函數。最后調用完后,"POP CX",恢復堆棧指針SP。
研究案例二
工具: Turboc C v2.0,Debug,MASM v5.0,NASM,TASM
實例C程序:
/* example1.c */
char ch;
extern void e_putchar(char c);
int e_main()
{
ch=0x44;
e_putchar(ch);
}
軟考備考資料免費領取
去領取
專注在線職業教育24年