I was tempted by this question of expand down segments, so I finally went ahead.
I used the well-known guides here and here.
I built up a real to protected mode program from scratch (see attachment) and then, when everything worked, I just switched the ED bit of my stack segment and converted the base and limits according to the guides. This is where things got funky.
First some code. My GDT looks like this:
Code: Select all
; GDT
GDT dw SIZE_GDT
dd 0 ; this is filled at later time
dw 0
descriptor <0ffffh,0,0,10011010b,0> ; code segment descr.
descriptor <0ffffh,0,0,10010010b,0> ; data segment descr.
descriptor <0ffffh-0400h,0,0,10010110b,0> ; stack segment descr.
Code: Select all
descriptor <0400h,0,0,10010010b,0> ; stack segment descr.
Code: Select all
lgdt fword ptr [GDT]
lidt fword ptr [NA] ; load NULL-IDT (prepare triple fault)
;TEMP CHECK
smsw ax
or ax,1
lmsw ax
jmpf 8,@F
@@:
mov ax,10h
mov ds,ax
mov es,ax
mov ax,18h
mov ss,ax ; <<< FAULTY INSTRUCTION
add sp,0ffffh-400h ; adjust SP
Code: Select all
mov bx,ss ; Prepare SS descriptor
xor ax,ax
call realtolin
add ax,400h ; BASE = LA + LIMIT
adc dl,0
dec dl ; according to guide: - modulus!
add di,8
mov (descriptor ptr [di]).base_l,ax
mov (descriptor ptr [di]).base_h,dl
Now, 2 things:
With the mov ss,ax instruction in place, the program is caught off via the "triple fault handler" (see full source code, I thought it's not really necessary to include it right here).
But when I replace this with mov es,ax, the computer hangs!
I also tried removing dec dl which seemed rather odd anyway (LA + Length - Modulus in Bob Smiths' guide) with nu apparent effect.
So I went ahead changed the code to this:
Code: Select all
mov ax,10h
mov ds,ax
mov es,ax
mov bx,18h
lar cx,bx
verr bx
lahf
mov al,ah
verw bx
lahf
Next stop: bochs. I figured I probably tripped an exception, so figuring out which one would definitely help. But this is completely weird now: the log is completely clogged with "BOUND_GdMa: fails bounds test". The clogging makes sense since the CPU places the address of the BOUND instruction on the stack, and the BIOS "handler" is just an iret. But why???
Interrupts are disabled, I do nothing with the stack, ... I really don't get it.