啟動(dòng)代碼怎么進(jìn)入c中的main函數(shù),?
注意三點(diǎn): 1,、如果要用到call指令,則必須建立堆棧,,也就是ss,sp要賦值,。 2、在匯編代碼中把main函數(shù)push到堆棧,,如果要讓main函數(shù)開始執(zhí)行,,則ret即可,因?yàn)閞et后會(huì)從堆棧中找到第一個(gè)IP,,然后彈出pop ip到指令寄存器,,CPU開始執(zhí)行main函數(shù),; 3、直接在匯編中跳轉(zhuǎn)到內(nèi)存的絕對物理地址開始執(zhí)行,,這就要求ld在連接的時(shí)候必須指定main函數(shù)在內(nèi)存中的地址,; 例如進(jìn)入保護(hù)模式后,我們要讓main函數(shù)開始執(zhí)行,,則通過指令跳轉(zhuǎn): jmp 08h:01000h ; Jump to section 08h (code), offset 01000h 上面的08h是16進(jìn)制數(shù)為段選擇符,,二進(jìn)制為1 0 00b,則為gdt中的第1項(xiàng),,根據(jù)gdt的設(shè)置,,我們此處知道是代碼段。在這里我們的代碼段的BASE ADDRESS是0,,所以我們的jmp的指令跳轉(zhuǎn)到的就是內(nèi)存地址0x1000處,。 如果cr0的31(PG--PAGE) ,0(PE--PROTECT ENABLE)位都開啟的話,這個(gè)地址還要通過頁變換才能變成物理地址,。 加載gdt的指令是lgdt,,指令所需操作數(shù)為6字節(jié),開始2字節(jié)為gdt表的大小,,后4字節(jié)為gdt表的地址,;gdt表裝到gdtr寄存器中。 所以:在我的BLOG中的“the os develop from boot begin”文章,,是使用上面3的方法進(jìn)入main 函數(shù)的,; 而LINUX內(nèi)核是通過上面2的方法進(jìn)入main 函數(shù)的 |
|