摘要:最開始的第一句CALL0003是我們用nasm編譯的start.asm所生成的代碼。我們主要目標(biāo)是研究藍(lán)色的C語言的代碼,第一句start.asm所生成的代碼太簡單,就是調(diào)用e_main函數(shù)。而我們的e_main函數(shù)就是藍(lán)色代碼部分。從C源程序中我們看到,我們?cè)趀_main做的就是一件事情:調(diào)用e_putchar(ch);其中ch是傳給出e_putchar的參數(shù)。MOVAX,000
我們主要目標(biāo)是研究藍(lán)色的C語言的代碼,第一句start.asm所生成的代碼太簡單,就是調(diào)用e_main函數(shù)。而我們的e_main函數(shù)就是藍(lán)色代碼部分。
從C源程序中我們看到,我們?cè)趀_main做的就是一件事情:調(diào)用e_putchar(ch);其中ch是傳給出e_putchar的參數(shù)。
MOV AX,000B
000B就是我們的全局變量ch所在內(nèi)存的地址。C語言會(huì)把所有的全局變量在另一塊內(nèi)存區(qū).C代碼先把ch的地址傳給AX,然后通過
PUSH AX
把AX的值,也就是ch的地址壓入堆棧。然后再
CALL 0020
而0020就是e_putchar代碼的地址。通過這跳語句,計(jì)算機(jī)就跳到e_putchar的代碼部分去執(zhí)行了.我在這里并不給出e_putchar的代碼,因?yàn)槲覀冞@個(gè)案例只是研究C語言中如何傳遞參數(shù)給其它函數(shù)的,并不管e_putchar如何取參數(shù)。下在一個(gè)案例中,我們將研究函數(shù)如何取參數(shù)。
在這里我得把CALL指令解釋清楚,因?yàn)樵谙聜€(gè)研究函數(shù)如何取參數(shù)的部分中大家可能會(huì)迷惑.CALL XXXX 指令簡單地或就是
PUSH IP
JMP XXXX
它首先把當(dāng)前的執(zhí)行地址IP壓入堆棧,然后跳轉(zhuǎn)到要CALL的地址去。CALL和RET指令是配套的。RET指令等同于
POP IP
也就是回復(fù)CALL前的執(zhí)行地址IP。
正因?yàn)檫@樣,所以你一旦使用了CALL指令,你的堆棧指針SP就會(huì)自動(dòng)減2。
POP CX
是每個(gè)函數(shù)調(diào)用完畢后都有的常用操作。在這里它不起任何作用??赡茏饔镁褪桥cCALL 0020前的PUSH AX像對(duì)應(yīng).這樣堆棧指針SP才能回原。
好了,簡單的第一個(gè)案例研究結(jié)束了。雖然就這4跳指令,但是我們已經(jīng)可以看出C語言傳遞參數(shù)方法了??偨Y(jié)起來就是通過"MOV AX,參數(shù)地址"把參數(shù)的地址傳到AX,然后"PUSH AX"把參數(shù)的地址壓入堆棧。最后"CALL 函數(shù)地址"轉(zhuǎn)向執(zhí)行要調(diào)用的函數(shù)。最后調(diào)用完后,"POP CX",恢復(fù)堆棧指針SP。
研究案例二
工具: Turboc C v2.0,Debug,MASM v5.0,NASM,TASM
實(shí)例C程序:
/* example1.c */
char ch;
extern void e_putchar(char c);
int e_main()
{
ch=0x44;
e_putchar(ch);
}
軟考備考資料免費(fèi)領(lǐng)取
去領(lǐng)取
共收錄117.93萬道題
已有25.02萬小伙伴參與做題