Şu anda düşük seviyeli programlama becerilerimi keskinleştirmek için x86 Assember ile uğraşıyorum. Şu anda, 32-Bit Korumalı Modda adresleme şeması ile küçük bir sorunla karşı karşıya.Assembler, Korunan Modda GDT ile atla
durum şudur:
Ben Korumalı Mod ile CPU geçer ve kodda göre etikete atlar 0x7e0 yüklenen bir Programı var:
[...]
code to switch CPU in Protected Mode
[...]
jmp ProtectedMode
[...]
bits 32
ProtectedMode:
.halt:
hlt
jmp .halt
Bu kesinlikle iyi böylece çalışır uzak. "Jmp ProtectedMode", ön yükleme kuyruğunu temizlemek için açık bir atlama olmadan çalışır - bu program, ofset 0 (başlangıçta orj 0) ile yüklendiğinden, kod parçasının doğru konuma işaret etmesine neden olur.
Şu anki sorunum şu ki, "ProtectedMode" etiketi içinde 0x8000'de yüklü olan başka bir programa atlamak istiyorum (bunu bir bellek dökümü ile kontrol ettim, yükleme işlevi düzgün çalışıyordu ve program yüklendi doğru 0x8000). İşlemci ProtectedMode şimdi ve artık realmode değil beri
, adresleme şeması farklıdır. ProtectedMode, belirli bir ofset eklemek ve fiziksel adresi (anladığım gibi) almak için bir temel adres ve bir tanımlayıcı tablosundaki bir sınırı aramak için tanımlayıcı seçicilerini kullanır. Bu nedenle, ProtectedMode girmeden önce bir GDT'nin kurulması gerekliydi. Şimdiye kadar is anlamadı ne
lgdt [gdtr]
, nasıl şimdi fiziksel atlamak yok yoluyla kayıt
%ifndef __GDT_INC_INCLUDED__
%define __GDT_INC_INCLUDED__
;*********************************
;* Global Descriptor Table (GDT) *
;*********************************
NULL_DESC:
dd 0 ; null descriptor
dd 0
CODE_DESC:
dw 0xFFFF ; limit low
dw 0 ; base low
db 0 ; base middle
db 10011010b ; access
db 11001111b ; granularity
db 0 ; base high
DATA_DESC:
dw 0xFFFF ; data descriptor
dw 0 ; limit low
db 0 ; base low
db 10010010b ; access
db 11001111b ; granularity
db 0 ; base high
gdtr:
Limit dw 24 ; length of GDT
Base dd NULL_DESC ; base of GDT
%endif ;__GDT_INC_INCLUDED__
ve GDT için yüklenir:
Mayın aşağıdaki gibi bakıyor GDT'yi kullanarak ProtectedMode'da adres 0x8000?
İlk düşüncelerim 0x7e00 (geçerli program yüklendi) olduğunu işaret eden Kod Tanımlayıcısı'nı (CODE_DESC) seçmek ve 0x8000'e (512 bayt) erişmek için gerekli olan atlama komutunu kullanmaktı ve atlama yönergesiyle sonuçlandı. :
jmp CODE_DESC:0x200
Ancak bu çalışmaz.
jmp 0x7e0:0x200
... ya çalışmıyor
Ona, burada eksik bir fikrin var mı? Belki 32-Bit ProtectedMode adresleme şeması ve GDT kullanımı içinde gerekli bir şey anlamadım.
[DÜZENLE] Komple kodu:
bits 16
org 0 ; loaded with offset 0000 (phys addr: 0x7e00)
jmp Start
Start:
xor ax, ax
mov ax, cs
mov ds, ax ; update data segment
cli ; clear interrupts
lgdt [gdtr] ; load GDT from GDTR (see gdt_32.inc)
call OpenA20Gate ; open the A20 gate
call EnablePMode ; jumps to ProtectedMode
;******************
;* Opens A20 Gate *
;******************
OpenA20Gate:
in al, 0x93 ; switch A20 gate via fast A20 port 92
or al, 2 ; set A20 Gate bit 1
and al, ~1 ; clear INIT_NOW bit
out 0x92, al
ret
;**************************
;* Enables Protected Mode *
;**************************
EnablePMode:
mov eax, cr0
or eax, 1
mov cr0, eax
jmp ProtectedMode ; this works (jumps to label and halts)
;jmp (CODE_DESC-NULL_DESC):ProtectedMode ; => does not work
;jmp 08h:ProtectedMode , => does not work
;***************
;* data fields *
;* &includes *
;***************
%include "gdt_32.inc"
;******************
;* Protected Mode *
;******************
bits 32
ProtectedMode:
;here I want to jump to physical addr 0x8000 (elf64 asm program)
.halt:
hlt
jmp .halt
Açıklama için teşekkürler ... İşte bu yüzden bunu yapıyorum - ve x86 referanslarını okuyarak ilk kez sıfırdan yaptığınız zaman bu kadar basit değil :)! Btw: Bu tür konuları tam olarak ele alan öğütler önerebileceğiniz harika bir kitap var mı? –
İyi kitaplar bilmiyorum. Intel ve AMD'nin resmi belgeleri tüm bilgilere sahiptir, sadece okuyabileceğiniz ve hemen her şeyi anlayacağınız tipik bir kitap ya da ders kitabı değildir (btw, Intel'in belgelerinde birçok yazım hatası ve zaman zaman hatalar vardır). Çevrimiçi birçok makale ve eğitici var. Ve her zaman deneyebilirsiniz. Ya da birinin kodunu gör ve soru sor. Şu gruplara bakın: [alt.os.development] (http://groups.google.com/group/alt.os.development/topics), [comp.lang.asm.x86] (http://groups.google .com/grup/comp.lang.asm.x86/başlık). –
Tavsiyeniz için teşekkürler! Buna bir bakacağım! –