欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
保護模式Protected Mode 簡(jiǎn)寫(xiě)為 pmode
保護模式, (Protected Mode,或有時(shí)簡(jiǎn)寫(xiě)為 pmode) 是一種 80286 系列和之后的 x86 兼容 CPU 操作模式。保護模式有一些新的特色,設計用來(lái)增強 多工 和系統穩定度,像是 內存保護,分頁(yè) 系統,以及硬件支援的 虛擬內存。大部分的現今 x86 操作系統 都在保護模式下運行,包含 Linux、FreeBSD、以及 微軟 Windows 2.0 和之后版本。
目錄
概況
What is GDT
Setup GDT
Load GDT
Other Preparing Stuff
Start Kernel
概況
另外一種 286 和其之后 CPU 的操作模式是 真實(shí)模式,一種向前兼容且關(guān)閉這些特色的模式。設計用來(lái)讓新的芯片可以執行舊的軟件。依照設計的規格,所有的 x86 CPU 都是在真實(shí)模式下開(kāi)機來(lái)確保傳統操作系統的向前兼容性。在任何保護模式的特色可用前,他們必須要由某些程序手動(dòng)地切換到保護模式。在現今的電腦,這種切換通常是由 操作系統 在開(kāi)機時(shí)候必須完成的第一件工作的一個(gè)。它也可能當 CPU 在保護模式下運行時(shí),使用 虛擬86模式 來(lái)執行設計給真實(shí)模式的程序碼。
盡管用軟件的方式也有某些可能在真實(shí)模式的系統下使用多工,但保護模式下內存保護的特色,可以避免有問(wèn)題的程序破壞其他工作或是 操作系統 核心所擁有的內存。保護模式也有中斷正在執行程序的硬件支援,可以把 execution content 交給其他工作,得以實(shí)現 先占式多工。
大部分可以使用保護模式的 CPU 也擁有 32 位元暫存器 的特色 (例如 80386 系列和其后任何的芯片),導入了融合保護模式而成為 32 位元處理的概念。80286 芯片雖有支援保護模式,但是仍然只有 16 位元暫存器。Windows 2.0 和之后版本中的保護模式增強稱(chēng)為 "386 增強模式",是因為他們除了保護模式外,還需要 32 位元的暫存器,并且無(wú)法在 286 上面執行 (即使 286 支援保護模式)。
即使在 32 位元芯片上已經(jīng)打開(kāi)了保護模式,但是 1 MB 以上的內存并無(wú)法存取,是由于一種仿照 IBM XT 系統設計特性的 memory wrap-around(內存連續) 的因素。這種限制可以由打開(kāi) A20 line 來(lái)回避。
在保護模式下,前面 32 個(gè)中斷都是保留給 CPU 例外處理用。舉個(gè)例子,中斷 0D (十進(jìn)制 13) 是 一般保護模式錯物 和 中斷 00 是 除以零。
在8086/8088時(shí)代,處理器只存在一種操作模式(Operation Mode),當時(shí)由于不存在其它操作模式,因此這種模式也沒(méi)有被命名。自從80286到80386開(kāi)始,處理器增加了另外兩種操作模式——保護模式PM (Protected Mode)和系統管理模式SMM(System Management Mode),因此,8086/8088的模式被命名為實(shí)地址模式RM(Real-address Mode)。
PM是處理器的native模式,在這種模式下,處理器支持所有的指令和所有的體系結構特性,提供最高的性能和兼容性。對于所有的新型應用程序和操作系統來(lái)說(shuō),建議都使用這種模式。為了保證PM的兼容性,處理器允許在受保護的,多任務(wù)的環(huán)境下執行RM程序。這個(gè)特性被稱(chēng)做虛擬8086模式(Virtual -8086 Mode),盡管它并不是一個(gè)真正的處理器模式。Virtual-8086模式實(shí)際上是一個(gè)PM的屬性,任何任務(wù)都可以使用它。
RM提供了Intel 8086處理器的編程環(huán)境,另外有一些擴展(比如切換到PM或SMM的能力)。當主機被Power-up或Reset后,處理器處于RM下。
SMM是一個(gè)對所有Intel處理器都統一的標準體系結構特性。出現于Intel386 SL芯片。這個(gè)模式為OS實(shí)現平臺指定的功能(比如電源管理或系統安全)提供了一種透明的機制。當外部的SMM interrupt pin(SMI#)被激活或者從APIC(Advanced Programming Interrupt Controller)收到一個(gè)SMI,處理器將進(jìn)入SMM。在SMM下,當保存當前正在運行程序的整個(gè)上下文(Context)時(shí),處理器切換到一個(gè)分離的地址空間。然后SMM指定的代碼或許被透明的執行。當從SMM返回時(shí),處理器將回到被系統管理中斷之前的狀態(tài)。
由于機器在Power-up或Reset之后,處理器處于RM狀態(tài),而對于Intel 80386以及其后的芯片,只有使用PM才能發(fā)揮出最大的作用。所以我們就面臨著(zhù)一個(gè)從RM切換到PM的問(wèn)題。
本文不討論SMM,本節的重點(diǎn)集中于在Booting階段如何從RM切換到PM,這里不會(huì )過(guò)多的討論PM的細節,因為《Intel Architecture Software Developer’s Manual Volume 3: System Programming》中有非常詳盡和準確的介紹。What is GDT
在Protected Mode下,一個(gè)重要的必不可少的數據結構就是GDT(Global Descriptor Table)。
為什么要有GDT?我們首先考慮一下在Real Mode下的編程模型:
在Real Mode下,我們對一個(gè)內存地址的訪(fǎng)問(wèn)是通過(guò)Segment:Offset的方式來(lái)進(jìn)行的,其中Segment是一個(gè)段的Base Address,一個(gè)Segment的最大長(cháng)度是64 KB,這是16-bit系統所能表示的最大長(cháng)度。而Offset則是相對于此Segment Base Address的偏移量。Base Address+Offset就是一個(gè)內存絕對地址。由此,我們可以看出,一個(gè)段具備兩個(gè)因素:Base Address和Limit(段的最大長(cháng)度),而對一個(gè)內存地址的訪(fǎng)問(wèn),則是需要指出:使用哪個(gè)段?以及相對于這個(gè)段Base Address的Offset,這個(gè)Offset應該小于此段的Limit。當然對于16-bit系統,Limit不要指定,默認為最大長(cháng)度64KB,而 16-bit的Offset也永遠不可能大于此Limit。我們在實(shí)際編程的時(shí)候,使用16-bit段寄存器CS(Code Segment),DS(Data Segment),SS(Stack Segment)來(lái)指定Segment,CPU將段積存器中的數值向左偏移4-bit,放到20-bit的地址線(xiàn)上就成為20-bit的Base Address。
到了Protected Mode,內存的管理模式分為兩種,段模式和頁(yè)模式,其中頁(yè)模式也是基于段模式的。也就是說(shuō),Protected Mode的內存管理模式事實(shí)上是:純段模式和段頁(yè)式。進(jìn)一步說(shuō),段模式是必不可少的,而頁(yè)模式則是可選的——如果使用頁(yè)模式,則是段頁(yè)式;否則這是純段模式。
既然是這樣,我們就先不去考慮頁(yè)模式。對于段模式來(lái)講,訪(fǎng)問(wèn)一個(gè)內存地址仍然使用Segment:Offset的方式,這是很自然的。由于 Protected Mode運行在32-bit系統上,那么Segment的兩個(gè)因素:Base Address和Limit也都是32位的。IA-32允許將一個(gè)段的Base Address設為32-bit所能表示的任何值(Limit則可以被設為32-bit所能表示的,以2^12為倍數的任何指),而不象Real Mode下,一個(gè)段的Base Address只能是16的倍數(因為其低4-bit是通過(guò)左移運算得來(lái)的,只能為0,從而達到使用16-bit段寄存器表示20-bit Base Address的目的),而一個(gè)段的Limit只能為固定值64 KB。另外,Protected Mode,顧名思義,又為段模式提供了保護機制,也就說(shuō)一個(gè)段的描述符需要規定對自身的訪(fǎng)問(wèn)權限(Access)。所以,在Protected Mode下,對一個(gè)段的描述則包括3方面因素:[Base Address, Limit, Access],它們加在一起被放在一個(gè)64-bit長(cháng)的數據結構中,被稱(chēng)為段描述符。這種情況下,如果我們直接通過(guò)一個(gè)64-bit段描述符來(lái)引用一個(gè)段的時(shí)候,就必須使用一個(gè)64-bit長(cháng)的段積存器裝入這個(gè)段描述符。但Intel為了保持向后兼容,將段積存器仍然規定為16-bit(盡管每個(gè)段積存器事實(shí)上有一個(gè)64-bit長(cháng)的不可見(jiàn)部分,但對于程序員來(lái)說(shuō),段積存器就是16-bit的),那么很明顯,我們無(wú)法通過(guò)16-bit長(cháng)度的段積存器來(lái)直接引用64-bit的段描述符。
怎么辦?解決的方法就是把這些長(cháng)度為64-bit的段描述符放入一個(gè)數組中,而將段寄存器中的值作為下標索引來(lái)間接引用(事實(shí)上,是將段寄存器中的高13 -bit的內容作為索引)。這個(gè)全局的數組就是GDT。事實(shí)上,在GDT中存放的不僅僅是段描述符,還有其它描述符,它們都是64-bit長(cháng),我們隨后再討論。
GDT可以被放在內存的任何位置,那么當程序員通過(guò)段寄存器來(lái)引用一個(gè)段描述符時(shí),CPU必須知道GDT的入口,也就是基地址放在哪里,所以Intel的設計者門(mén)提供了一個(gè)寄存器GDTR用來(lái)存放GDT的入口地址,程序員將GDT設定在內存中某個(gè)位置之后,可以通過(guò)LGDT指令將GDT的入口地址裝入此積存器,從此以后,CPU就根據此積存器中的內容作為GDT的入口來(lái)訪(fǎng)問(wèn)GDT了。
GDT是Protected Mode所必須的數據結構,也是唯一的——不應該,也不可能有多個(gè)。另外,正象它的名字(Global Descriptor Table)所揭示的,它是全局可見(jiàn)的,對任何一個(gè)任務(wù)而言都是這樣。
除了GDT之外,IA-32還允許程序員構建與GDT類(lèi)似的數據結構,它們被稱(chēng)作LDT(Local Descriptor Table),但與GDT不同的是,LDT在系統中可以存在多個(gè),并且從LDT的名字可以得知,LDT不是全局可見(jiàn)的,它們只對引用它們的任務(wù)可見(jiàn),每個(gè)任務(wù)最多可以擁有一個(gè)LDT。另外,每一個(gè)LDT自身作為一個(gè)段存在,它們的段描述符被放在GDT中。
IA-32為L(cháng)DT的入口地址也提供了一個(gè)寄存器LDTR,因為在任何時(shí)刻只能有一個(gè)任務(wù)在運行,所以L(fǎng)DT寄存器全局也只需要有一個(gè)。如果一個(gè)任務(wù)擁有自身的LDT,那么當它需要引用自身的LDT時(shí),它需要通過(guò)LLDT將其LDT的段描述符裝入此寄存器。LLDT指令與LGDT指令不同的時(shí),LGDT指令的操作數是一個(gè)32-bit的內存地址,這個(gè)內存地址處存放的是一個(gè)32-bit GDT的入口地址,以及16-bit的GDT Limit。而LLDT指令的操作數是一個(gè)16-bit的選擇子,這個(gè)選擇子主要內容是:被裝入的LDT的段描述符在GDT中的索引值——這一點(diǎn)和剛才所討論的通過(guò)段積存器引用段的模式是一樣的。
LDT只是一個(gè)可選的數據結構,你完全可以不用它。使用它或許可以帶來(lái)一些方便性,但同時(shí)也帶來(lái)復雜性,如果你想讓你的OS內核保持簡(jiǎn)潔性,以及可移植性,則最好不要使用它。
引用GDT和LDT中的段描述符所描述的段,是通過(guò)一個(gè)16-bit的數據結構來(lái)實(shí)現的,這個(gè)數據結構叫做Segment Selector——段選擇子。它的高13位作為被引用的段描述符在GDT/LDT中的下標索引,bit 2用來(lái)指定被引用段描述符被放在GDT中還是到LDT中,bit 0和bit 1是RPL——請求特權等級,被用來(lái)做保護目的,我們這里不詳細討論它。
前面所討論的裝入段寄存器中作為GDT/LDT索引的就是Segment Selector,當需要引用一個(gè)內存地址時(shí),使用的仍然是Segment:Offset模式,具體操作是:在相應的段寄存器裝入Segment Selector,按照這個(gè)Segment Selector可以到GDT或LDT中找到相應的Segment Descriptor,這個(gè)Segment Descriptor中記錄了此段的Base Address,然后加上Offset,就得到了最后的內存地址。如下圖所示:Setup GDT
由上一節的討論得知,GDT是Protected Mode所必須的數據結構,那么我們在進(jìn)入Protected Mode之前,必須設定好GDT,并通過(guò)LGDT將其裝入相應的寄存器。
盡管GDT允許被放在內存的任何位置,但由于GDT中的元素——描述符——都是64-bit長(cháng),也就是說(shuō)都是8個(gè)字節,所以為了讓CPU對GDT的訪(fǎng)問(wèn)速度達到最快,我們應該將GDT的入口地址放在以8個(gè)字節對齊,也就是說(shuō)是8的倍數的地址位置。
GDT中第一個(gè)描述符必須是一個(gè)空描述符,也就是它的內容應該全部為0。如果引用這個(gè)描述符進(jìn)行內存訪(fǎng)問(wèn),則是產(chǎn)生General Protection異常。
如果一個(gè)OS不使用虛擬內存,段模式會(huì )是一個(gè)不錯的選擇。但現代OS沒(méi)有不使用虛擬內存的,而實(shí)現虛擬內存的比較方便和有效的內存管理方式是頁(yè)式管理。但是在IA-32上如果我們想使用頁(yè)式管理,我們只能使用段頁(yè)式——沒(méi)有方法可以完全禁止段模式。但我們可以盡力讓段的效果降低的最小。
IA-32提供了一種被稱(chēng)作“Basic Flat Model”的分段模式可以達到這種效果。這種模式要求在GDT中至少要定義兩個(gè)段描述符,一個(gè)用來(lái)引用Data Segment,另一個(gè)用來(lái)引用Code Segment。這2個(gè)Segment都包含整個(gè)線(xiàn)性空間,即Segment Limit = 4 GB,即使實(shí)際的物理內存遠沒(méi)有那么多,但這個(gè)空間定義是為了將來(lái)由頁(yè)式管理來(lái)實(shí)現虛擬內存。
在這里,我們只是處于Booting階段,所以我們只需要初步設置一下GDT,等真正進(jìn)入Protected Mode,啟動(dòng)了OS Kernel之后,具體OS打算如何設置GDT,使用何種內存管理模式,由Kernel自身來(lái)設置,Booting只需要給Kernel的數據段和代碼段設置全部線(xiàn)性空間就可以了。
段描述符的格式如下圖所示:
具體到代碼段和數據段,它們的格式如下圖所示:
下面就是在Booting階段為進(jìn)入Protected Mode而設置的臨時(shí)的gdt。這里定義了3個(gè)段描述符:第一個(gè)是系統規定的空描述符,第2個(gè)是引用4 GB線(xiàn)性空間的代碼段,第3個(gè)是引用4 GB線(xiàn)性空間的數據段。這是"Basic Flat Model"所要求的最下GDT設置,但就booting階段,只是為了進(jìn)入Protected Mode,并為內核提供一個(gè)連續的,最大的線(xiàn)性空間這個(gè)目的而言,已經(jīng)足夠了。
# Descriptor tables
gdt:
.word 0, 0, 0, 0 # dummy
.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 # base address = 0
.word 0x9A00 # code read/exec
.word 0x00CF # granularity = 4096, 386
# (+5th nibble of limit)
.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 # base address = 0
.word 0x9200 # data read/write
.word 0x00CF # granularity = 4096, 386
# (+5th nibble of limit)Load GDT
設置好GDT之后,我們需要通過(guò)LGDT指令將設定的gdt的入口地址和gdt表的大小裝入GDTR寄存器。
GDTR寄存器包括兩部分:32-bit的線(xiàn)性基地址,以及16-bit的GDT大?。ㄒ宰止潪閱挝唬?。需要注意的是,對于32-bit線(xiàn)性基地址,必須是32-bit絕對物理地址,而不是相對于某個(gè)段的偏移量。而我們在Booting階段,在進(jìn)入Protected Mode之前,我們CS和DS設置很可能不是0,所以我們必須計算出gdt的絕對物理地址。
為了執行LGDT指令,你需要把這兩部分內容放在內存的某個(gè)位置,然后將這個(gè)位置的內存地址作為操作數傳遞給LGDT指令。然后LGDT指令會(huì )自動(dòng)將保存在這個(gè)位置的這兩部分值裝入GDTR寄存器。
# 這是存放GDTR所需的兩部分內容的位置
gdt_48:
.word 0x8000 # gdt limit=2048,
# 256 GDT entries
.word 0, 0 # gdt base (filled in later)
# 下面這段代碼用來(lái)計算GDT的32-bit線(xiàn)性地址,并將其裝入GDTR寄存器。
xorl %eax, %eax # Compute gdt_base
movw %ds, %ax # (Convert %ds:gdt to a linear ptr)
shll , %eax
addl $gdt, %eax
movl %eax, (gdt_48+2)
lgdt gdt_48 # load gdt with whatever is appropriateOther Preparing Stuff
在進(jìn)入Protected Mode之前,除了需要設置和裝入GDT之外,還需要做如下一些事情:
屏蔽所有可屏蔽中斷;
裝入IDTR;
所有協(xié)處理器被正確的Reset。
由于在Real Mode和Protected Mode下的中斷處理機制有一些不同,所以在進(jìn)入Protected Mode之前,務(wù)必禁止所有可屏蔽中斷,這可以通過(guò)下面兩種方法之一:
使用CLI指令;
對8259A可編程中斷控制器編程以屏蔽所有中斷。
即使當我們進(jìn)入Protected Mode之后,也不能馬上將中斷打開(kāi),這時(shí)因為我們必須在OS Kernel中對相關(guān)的Protected Mode中斷處理所需的數據結構正確的初始化之后,才能打開(kāi)中斷,否則會(huì )產(chǎn)生處理器異常。
在Real Mode下,中斷處理使用IVT(Interrupt Vector Table),在Protected Mode下,中斷處理使用IDT(Interrupt Descriptor Table),所以,我們必須在進(jìn)入Protected Mode之前設置IDTR。
IDTR的格式和GDTR相同,IDTR的裝入方式和GDTR也相同。由于IDT中相關(guān)的中斷處理程序需要讓OS Kernel來(lái)設定,所以在Booting階段,我們只需要將IDTR中IDT的基地址和Size都設為0就可以了,隨后,等進(jìn)入Protected Mode之后,由OS Kernel來(lái)真正設置它。
關(guān)于中斷機制和中斷處理,請參考 Interrupt & Exception ,這里不再贅述。
#
# 這是存放IDTR所需的兩部分內容的位置
#
idt_48:
.word 0 # idt limit = 0
.word 0, 0 # idt base = 0L
# 對于IDTR的處理,只需要這一條指令即可
lidt idt_48 # load idt with 0,0
#
# 通過(guò)設置8259A PIC,屏蔽所有可屏蔽中斷
#
movb xFF, %al # mask all interrupts for now
outb %al, xA1
call delay
movb xFB, %al # mask all irq's but irq2 which
outb %al, x21 # is cascaded
# 保證所有的協(xié)處理都被正確的Reset
xorw %ax, %ax
outb %al, xf0
call delay
outb %al, xf1
call delay
# Delay is needed after doing I/O
delay:
outb %al,x80
ret
5. Let's Go
好了,一切準備就緒,Fire!:)
進(jìn)入Protected Mode,還是進(jìn)入Real Mode,完全靠CR0寄存器的PE標志位來(lái)控制:如果PE=1,則CPU切換到PM,否則,則進(jìn)入RM。
設置CR0-PE位的方法有兩種:
第一種是80286所使用的LMSW指令,后來(lái)的80386及更高型號的CPU為了保持向后兼容,都保留了這個(gè)指令。這個(gè)指令只能影響最低的4 bit,即PE,MP,EM和TS,對其它的沒(méi)有影響。
#
#通過(guò)LMSW指令進(jìn)入Protected Mode
#
movw , %ax # protected mode (PE) bit
lmsw %ax # This is it!
第二種是Intel所建議的在80386以后的CPU上使用的進(jìn)入PM的方式,即通過(guò)MOV指令。MOV指令可以設置CR0寄存器的所有域的值。
#
#通過(guò)MOV指令進(jìn)入Protected Mode
#
movl %cr0, %eax
xorb , %al # set PE = 1
movl %eax, %cr0 # go!!
OK,現在已經(jīng)進(jìn)入Protected Mode了。
很簡(jiǎn)單,right?But It's not over yet!Start Kernel
我們已經(jīng)從Real Mode進(jìn)入Protected Mode,現在我們馬上就要啟動(dòng)OS Kernel了。
OS Kernel運行在32-bit段模式,而當前我們卻仍然處于16-bit段模式。這是怎么回事?為了了解這個(gè)問(wèn)題,我們需要仔細探討一下IA-32的段模式的實(shí)現方法。
IA-32共提供了6個(gè)16-bit段寄存器:CS,DS,SS,ES,FS,GS。但事實(shí)上,這16-bit只是對程序員可見(jiàn)的部分,但每個(gè)寄存器仍然包括64-bit的不可見(jiàn)部分。
可見(jiàn)部分是為了供程序員裝載段寄存器,但一旦裝載完成,CPU真正使用的就只是不可見(jiàn)部分,可見(jiàn)部分就完全沒(méi)有用了。
不可見(jiàn)部分存放的內容是什么?具體格式我沒(méi)有看到相關(guān)資料,但可以確定的是隱藏部分的內容和段描述符的內容是一致的(請參考段描述的格式),只不過(guò)格式可能不完全相同。但格式對我們理解這一點(diǎn)并不重要,因為程序員不可能能夠直接操作它。
我們以CS寄存器為例,對于其它寄存器也是一樣的:
在Real Mode下,當我們執行一個(gè)裝載CS寄存器的指令的時(shí)候(jmp,call,ret等),相關(guān)的值會(huì )被裝入CS寄存器的可見(jiàn)部分,但同時(shí)CPU也會(huì )根據可見(jiàn)部分的內容來(lái)設置不可見(jiàn)部分。比如我們執行"ljmp x1234, $go "之后,CS寄存器的可見(jiàn)部分的內容就是1234h,同時(shí),不可見(jiàn)部分的32-bit Base Address域被設置為00001234h,20-bit的Limit域被設置為固定值10000h,也就是64 KB,Access Information部分的其它值我們不去考慮,只考慮其D/B位,由于執行此指令時(shí)處于Real Mode模式,所以D/B被設置為0,表示此段是一個(gè)16-bit段。當對CS寄存器的可見(jiàn)部分和不可見(jiàn)部分的內容都被設置之后,CS寄存器的裝載工作完成。隨后當CPU需要通過(guò)CS的內容進(jìn)行地址運算的時(shí)候,則僅僅引用不可見(jiàn)部分。
在Protected Mode下,當我們執行一個(gè)裝載CS寄存器的指令的時(shí)候,段選擇子(Segment Selector)被裝入CS寄存器的可見(jiàn)部分,同時(shí)CPU根據此選擇子到相應的描述符表中(GDT或LDT)找到相應的段描述符并將其內容裝載入CS寄存器的不可見(jiàn)部分。隨后CPU當需要通過(guò)CS的內容進(jìn)行地址運算的時(shí)候,也僅僅引用不可見(jiàn)部分。
從上面的描述可以看出,事實(shí)上CPU在引用段寄存器的內容進(jìn)行地址運算時(shí),Real Mode和Protected Mode是一致的。另外,也明白了為什么我們在Real Mode下設置的段寄存器的內容到了Protected Mode下仍然引用的是16-bit段。
那么我們如何將CS設置為引用32-bit段?方法就像我們前面所討論的,使用jmp或call指令,引用一個(gè)段選擇子,到GDT中裝載一個(gè)引用32-bit段的段描述符。
需要注意的是,如果CS寄存器的內容指出當前是一個(gè)16-bit段,那么當前的地址模式也就是16-bit地址模式,這與你當前是出于Real Mode還是Protected Mode無(wú)關(guān)。而我們裝載32-bit段的jmp指令或call指令必須使用的是32-bit地址模式。而我們當前的boot部分代碼是16-bit代碼,所以我們必須在此jmp/call指令前加上地址轉換前綴代碼66h。
下面的例子就是使用jmp指令裝入32-bit段。Jmpi指令的含義是段間跳轉,其Opcode為Eah,其格式為:jmpi Offset, Segment Selector。
# 由于當前的代碼是16-bit代碼,而我們要執行32-bit地址模式的指令,指令前
# 需要有地址模式切換前綴66h,如果我們直接寫(xiě)jmp指令,由編譯器來(lái)生成代碼
# 的話(huà),是無(wú)法作到這一點(diǎn)的,所以我們直接寫(xiě)相關(guān)數據。
.byte 0x66, 0xea # prefix + jmpi-opcode
.long 0x1000 # Offset
.word __KERNEL_CS # CS segment selector
上面的代碼相當于32-bit指令:
jmpi 0x1000,__KERNEL_CS
如果__KERNEL_CS段選擇子所引用的段描述符設置的段空間為線(xiàn)形地址[0,4 GB],而我們將OS Kernel放在物理地址1000h,那么此jmpi指令就跳轉到OS Kernel的入口處,并開(kāi)始執行它。
此時(shí),Booting階段結束,OS正式開(kāi)始運行!
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
保護模式簡(jiǎn)介
【實(shí)現操作系統05】完善Loader程序,并加載內核(下)
Windows內存管理
80x86保護模式系列教程(三.控制寄存器和系統地址寄存器)
操作系統啟動(dòng)過(guò)程
一口氣看完45個(gè)寄存器,CPU核心技術(shù)大揭秘
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久