매우 간단한 부트 로더에서 보호 모드로 실행하기 전에 데이터 세그먼트 (ds)에 무언가를 할당하면 프로세서 오류가 발생한다는 것을 발견했습니다.데이터 세그먼트가 0이 아니면 보호 모드가 실패합니다
이 코드는 잘 작동합니다 :
[BITS 16]
[ORG 0x7c00]
xor ax,ax
mov ds,ax
cli
lgdt [gdt_descriptor]
mov eax, cr0
or eax,1
mov cr0, eax
jmp CODE_SEG:now
[BITS 32]
now:
jmp $
db 0
gdt_start:
gdt_null:
dd 0x0
dd 0x0
gdt_cs:
dw 0xFFFF ; Limit
dw 0x0000 ; Base
db 0x0000 ; Base 23:16
db 10011011b
db 11011111b
db 0x0000
gdt_ds:
dw 0xFFFF ; Limit
dw 0x0000 ; Base
db 0x0000 ; Base 23:16
db 10010011b
db 11011111b
db 0x0000
gdt_end
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_cs - gdt_start
DATA_SEG equ gdt_ds - gdt_start
times 510-($-$$) db 0 ; fill sector w/ 0's
db 0x55 ; req'd by some BIOSes
db 0xAA
이것은 하나의 프로세서를 다시 시작합니다 :
[BITS 16]
[ORG 0x7c00]
mov ax,0x10 ;<-- Pre-assigning data segment
mov ds,ax
cli
lgdt [gdt_descriptor]
mov eax, cr0
or eax,1
mov cr0, eax
jmp CODE_SEG:now
[BITS 32]
now:
jmp $
db 0
gdt_start:
gdt_null:
dd 0x0
dd 0x0
gdt_cs:
dw 0xFFFF ; Limit
dw 0x0000 ; Base
db 0x0000 ; Base 23:16
db 10011011b
db 11011111b
db 0x0000
gdt_ds:
dw 0xFFFF ; Limit
dw 0x0000 ; Base
db 0x0000 ; Base 23:16
db 10010011b
db 11011111b
db 0x0000
gdt_end
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_cs - gdt_start
DATA_SEG equ gdt_ds - gdt_start
times 510-($-$$) db 0 ; fill sector w/ 0's
db 0x55 ; req'd by some BIOSes
db 0xAA
나는 NASM과 함께이 컴파일 내가 VM웨어와 함께 달렸다.
왜 이런 일이 발생합니까?
'ds'를 잘못된 값으로로드하고 있습니다. 왜 그것이 작동하기를 기대합니까? –
여기서 문서는 ds가 보호 모드를로드하는 긴 점프 전에 0이 아니어야한다고 지정합니다. 그 외에도 0x10은 올바른 값입니다. 보호 모드로 점프 한 후 0x10으로 ds를 설정하면 정상적으로 작동합니다. – felknight
@ Felipe : Jonathon의 대답은 정확합니다. 그러나 당신이 지금 가지고있는 하나의 특정한 문제에 대해서만 접촉합니다. 잘못된 정보 ("ds는 점프 전에 0이 아니어야합니다.")에 의존하는 것을 비롯하여 실제 모드 세그먼트로드와 보호 모드 세그먼트로드 사이의 차이점을 이해하지 못하고 BIOS가 특정 상태로 특정 레지스터를 남겨 둔다고 잘못 가정합니다 부트 로더의 처음 512 바이트에서 보호 모드로 전환하더라도 설계상의 실수입니다. – Brendan