本匯編代碼對(duì)應(yīng)保戶模式下操作系統(tǒng)內(nèi)核如何加載用戶程序并運(yùn)行 的實(shí)際主引導(dǎo)扇區(qū)代碼:
- 對(duì)應(yīng)的內(nèi)核代碼在:內(nèi)核代碼
- 對(duì)應(yīng)的用戶程序代碼在:用戶程序代碼
;代碼清單
13-1;文件名:c13_mbr
.asm;文件說(shuō)明:硬盤主引導(dǎo)扇區(qū)代碼
;創(chuàng)建日期:
2011-10-28 22:35 ;設(shè)置堆棧段和棧指針 core_base_address equ
0x00040000 ;常數(shù),內(nèi)核加載的起始內(nèi)存地址 core_start_sector equ
0x00000001 ;常數(shù),內(nèi)核的起始邏輯扇區(qū)號(hào) mov ax
,cs mov ss
,axmov sp
,0x7c00;計(jì)算GDT所在的邏輯段地址mov eax
,[cs
:pgdt
+0x7c00+0x02] ;GDT的
32位物理地址 xor edx
,edxmov ebx
,16div ebx
;分解成
16位邏輯地址 mov ds
,eax
;令DS指向該段以進(jìn)行操作mov ebx
,edx
;段內(nèi)起始偏移地址
;跳過(guò)
0#號(hào)描述符的槽位
;創(chuàng)建
1#描述符,這是一個(gè)數(shù)據(jù)段,對(duì)應(yīng)
0~4GB的線性地址空間mov dword
[ebx
+0x08],0x0000ffff ;基地址為
0,段界限為
0xFFFFFmov dword
[ebx
+0x0c],0x00cf9200 ;粒度為
4KB,存儲(chǔ)器段描述符
;創(chuàng)建保護(hù)模式下初始代碼段描述符mov dword
[ebx
+0x10],0x7c0001ff ;基地址為
0x00007c00,界限
0x1FF mov dword
[ebx
+0x14],0x00409800 ;粒度為
1個(gè)字節(jié),代碼段描述符
;建立保護(hù)模式下的堆棧段描述符
;基地址為
0x00007C00,界限
0xFFFFE mov dword
[ebx
+0x18],0x7c00fffe ;粒度為
4KB mov dword
[ebx
+0x1c],0x00cf9600;建立保護(hù)模式下的顯示緩沖區(qū)描述符 mov dword
[ebx
+0x20],0x80007fff ;基地址為
0x000B8000,界限
0x07FFF mov dword
[ebx
+0x24],0x0040920b ;粒度為字節(jié)
;初始化描述符表寄存器GDTRmov word
[cs
: pgdt
+0x7c00],39 ;描述符表的界限 lgdt
[cs
: pgdt
+0x7c00]in al
,0x92 ;南橋芯片內(nèi)的端口 or al
,0000_0010Bout
0x92,al
;打開A20cli
;中斷機(jī)制尚未工作mov eax
,cr0or eax
,1mov cr0
,eax
;設(shè)置PE位
;以下進(jìn)入保護(hù)模式
... ...jmp dword
0x0010:flush
;16位的描述符選擇子:
32位偏移
;清流水線并串行化處理器
[bits
32] flush
: mov eax
,0x0008 ;加載數(shù)據(jù)段
(0..4GB
)選擇子mov ds
,eaxmov eax
,0x0018 ;加載堆棧段選擇子 mov ss
,eaxxor esp
,esp
;堆棧指針
<- 0 ;以下加載系統(tǒng)核心程序 mov edi
,core_base_address mov eax
,core_start_sectormov ebx
,edi
;起始地址 call read_hard_disk_0
;以下讀取程序的起始部分(一個(gè)扇區(qū))
;以下判斷整個(gè)程序有多大mov eax
,[edi
] ;核心程序尺寸xor edx
,edx mov ecx
,512 ;512字節(jié)每扇區(qū)div ecxor edx
,edxjnz @
1 ;未除盡,因此結(jié)果比實(shí)際扇區(qū)數(shù)少
1 dec eax
;已經(jīng)讀了一個(gè)扇區(qū),扇區(qū)總數(shù)減
1 @
1:or eax
,eax
;考慮實(shí)際長(zhǎng)度≤
512個(gè)字節(jié)的情況 jz setup
;EAX
=0 ?;讀取剩余的扇區(qū)mov ecx
,eax
;32位模式下的LOOP使用ECXmov eax
,core_start_sectorinc eax
;從下一個(gè)邏輯扇區(qū)接著讀@
2:call read_hard_disk_0inc eaxloop @
2 ;循環(huán)讀,直到讀完整個(gè)內(nèi)核 setup
:mov esi
,[0x7c00+pgdt
+0x02] ;不可以在代碼段內(nèi)尋址pgdt,但可以
;通過(guò)
4GB的段來(lái)訪問(wèn)
;建立公用例程段描述符mov eax
,[edi
+0x04] ;公用例程代碼段起始匯編地址mov ebx
,[edi
+0x08] ;核心數(shù)據(jù)段匯編地址sub ebx
,eaxdec ebx
;公用例程段界限 add eax
,edi
;公用例程段基地址mov ecx
,0x00409800 ;字節(jié)粒度的代碼段描述符call make_gdt_descriptormov
[esi
+0x28],eaxmov
[esi
+0x2c],edx
;建立核心數(shù)據(jù)段描述符mov eax
,[edi
+0x08] ;核心數(shù)據(jù)段起始匯編地址mov ebx
,[edi
+0x0c] ;核心代碼段匯編地址 sub ebx
,eaxdec ebx
;核心數(shù)據(jù)段界限add eax
,edi
;核心數(shù)據(jù)段基地址mov ecx
,0x00409200 ;字節(jié)粒度的數(shù)據(jù)段描述符 call make_gdt_descriptormov
[esi
+0x30],eaxmov
[esi
+0x34],edx
;建立核心代碼段描述符mov eax
,[edi
+0x0c] ;核心代碼段起始匯編地址mov ebx
,[edi
+0x00] ;程序總長(zhǎng)度sub ebx
,eaxdec ebx
;核心代碼段界限add eax
,edi
;核心代碼段基地址mov ecx
,0x00409800 ;字節(jié)粒度的代碼段描述符call make_gdt_descriptormov
[esi
+0x38],eaxmov
[esi
+0x3c],edxmov word
[0x7c00+pgdt
],63 ;描述符表的界限lgdt
[0x7c00+pgdt
] jmp far
[edi
+0x10] ;-------------------------------------------------------------------------------
read_hard_disk_0
: ;從硬盤讀取一個(gè)邏輯扇區(qū)
;EAX
=邏輯扇區(qū)號(hào)
;DS
:EBX
=目標(biāo)緩沖區(qū)地址
;返回:EBX
=EBX
+512 push eax push ecxpush edxpush eaxmov dx
,0x1f2mov al
,1out dx
,al
;讀取的扇區(qū)數(shù)inc dx
;0x1f3pop eaxout dx
,al
;LBA地址
7~0inc dx
;0x1f4mov cl
,8shr eax
,clout dx
,al
;LBA地址
15~8inc dx
;0x1f5shr eax
,clout dx
,al
;LBA地址
23~16inc dx
;0x1f6shr eax
,clor al
,0xe0 ;第一硬盤 LBA地址
27~24out dx
,alinc dx
;0x1f7mov al
,0x20 ;讀命令out dx
,al
.waits
:in al
,dxand al
,0x88cmp al
,0x08jnz
.waits
;不忙,且硬盤已準(zhǔn)備好數(shù)據(jù)傳輸 mov ecx
,256 ;總共要讀取的字?jǐn)?shù)mov dx
,0x1f0.readw
:in ax
,dxmov
[ebx
],axadd ebx
,2loop
.readwpop edxpop ecxpop eaxret
;-------------------------------------------------------------------------------
make_gdt_descriptor
: ;構(gòu)造描述符
;輸入:EAX
=線性基地址
; EBX
=段界限
; ECX
=屬性(各屬性位都在原始
; 位置,其它沒(méi)用到的位置
0)
;返回:EDX
:EAX
=完整的描述符mov edx
,eaxshl eax
,16 or ax
,bx
;描述符前
32位
(EAX
)構(gòu)造完畢and edx
,0xffff0000 ;清除基地址中無(wú)關(guān)的位rol edx
,8bswap edx
;裝配基址的
31~24和
23~16 (80486+)xor bx
,bxor edx
,ebx
;裝配段界限的高
4位or edx
,ecx
;裝配屬性 ret
;-------------------------------------------------------------------------------pgdt dw
0dd
0x00007e00 ;GDT的物理地址
;------------------------------------------------------------------------------- times
510-($
-$$
) db
0db
0x55,0xaa
總結(jié)
以上是生活随笔為你收集整理的【OS学习笔记】二十 保护模式六:保户模式下操作系统内核如何加载用户程序并运行 对应的汇编代码之主引导扇区程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。