현재 저수준 프로그래밍 기술을 향상시키기 위해 x86 Assember를 사용 중입니다. 현재 32 비트 보호 모드에서 주소 지정 체계에 약간의 문제가 있습니다.어셈블러가 GDT로 보호 모드로 점프합니다.
상황은 다음
나는 보호 모드로 CPU를 전환하고 코드에 따라 라벨로 점프 0x7e0로드 프로그램이 있습니다
이[...]
code to switch CPU in Protected Mode
[...]
jmp ProtectedMode
[...]
bits 32
ProtectedMode:
.halt:
hlt
jmp .halt
이 절대적으로 좋은 때문에 작동을 멀리. "jmp ProtectedMode"는 프리 페치 대기열을 지우는 명시 적 먼 점프없이 작동합니다.이 프로그램은 오프셋 0 (처음에는 org 0)이로드되어 코드 세그먼트가 올바른 위치를 가리 키도록합니다.
현재 "ProtectedMode"레이블에서 0x8000으로로드 된 다른 프로그램으로 점프하고 싶습니다. (메모리 덤프로 검사했는데로드 기능이 제대로 작동하고 프로그램이로드되었습니다. 올바르게 0x8000).
CPU가 이제 ProtectedMode에 있고 RealMode가 아니기 때문에 주소 지정 스키마가 다릅니다. ProtectedMode는 설명자 선택기를 사용하여 디스크립터 테이블의 기본 주소와 제한을 조회하여 주어진 오프셋을 추가하고 실제 주소를 검색합니다 (필자의 이해대로). 따라서 ProtectedMode를 시작하기 전에 GDT를 설치해야합니다. 지금까지 이해하지 않았다 무엇
lgdt [gdtr]
, 어떻게 지금 물리적으로 이동 않습니다를 통해 등록
%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__
와 GDT에로드됩니다
광산은 다음과 같이보고있다 GDT를 사용하는 ProtectedMode의 주소 0x8000?
첫 번째 생각은 0x7e00 (현재 프로그램이로드 됨)을 가리켜 야하는 코드 설명자 (CODE_DESC)를 선택하고 0x8000 (512 바이트)에 도달하는 데 필요한 오프셋을 사용하여 점프 명령 :
jmp CODE_DESC:0x200
그러나이 작동하지 않습니다.
jmp 0x7e0:0x200
... 중 하나가 작동하지 않습니다
당신은 내가 여기에 놓친 거지 어떤 생각을 가지고 있습니까? 어쩌면 32 비트 ProtectedMode 주소 지정 체계와 GDT의 사용에 필수적인 것을 이해하지 못했을 수도 있습니다.
[편집] 전체 코드 :
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
설명을 주셔서 감사합니다 ... 이것은 정확히 내가 이것을하고있는 이유입니다 - 그리고 처음에 x86 참고 문헌을 읽음으로써 처음부터 이것을 할 때 그렇게 간단하지 않습니다 :)! Btw : 이러한 주제 유형을 정확히 처리 할 수있는 훌륭한 책이 있습니까? –
나는 좋은 책을 모른다. 인텔과 AMD의 공식 문서는 모든 정보를 담고 있으며, 쉽게 읽을 수있는 책이나 교과서의 일반적인 종류가 아니며, 모든 것을 즉시 이해합니다 (btw, 인텔 오피스의 많은 오타 및 가끔 실수가 있음). 많은 기사 및 온라인 자습서가 있습니다. 그리고 당신은 항상 실험을 할 수 있습니다. 또는 누군가의 코드를보고 질문을하십시오. 다음 그룹을 참조하십시오 : [alt.os.development] (http://groups.google.com/group/alt.os.development/topics), [comp.lang.asm.x86] (http://groups.google .com/group/comp.lang.asm.x86/topics). –
조언 해 주셔서 감사합니다. 나는 그것을 볼 것이다! –