Switching to protected mode from DOS not using DPMI
Asked Answered
B

1

1

I learned x86-16 assembly and i want to learn to x86-32 assembly. I maked a simple 32-bit program but this code not work When program makes a far jump console displays 'JMP illegal descriptor 0' I use fasm and DOS Please show me what i'm doing bad

Here's my code

format MZ

push cs
pop ds
mov eax,cs
shl eax,4
mov [AdresSegmentuProgramu_32],eax ;Calculating real mode segment
add eax,gdt_table
mov [gdtr+2],eax
use32
lgdt [gdtr]


mov eax,[AdresSegmentuProgramu_32]
add eax,pmode_entry
mov [AdresSegmentu_PMODE_entry],eax

mov eax,cr0
or eax,1    ;Switch to PMODE
mov cr0,eax

mov eax,[AdresSegmentu_PMODE_entry] ;Far jump to reset CS and jump to simple code
mov [far_jump],eax


jmp far [ds:far_jump]

far_jump:
dd 0
dw 08h ; Selector 0x08

gdtr: dw 128
dd 0


AdresSegmentuProgramu_32 dd 0
AdresSegmentu_PMODE_entry dd 0

use32

gdt_table:
dq 0
code_descriptor:
dw 0ffffh
dw 0
db 0
db 09ah
db 11001111b
db 0
data_descriptor:
dw 0ffffh
dw 0
db 0
db 092h
db 11001111b
db 0

dq 0
dq 0

pmode_entry:

mov esi,0b8000h
mov byte [esi],'a'
Brunhild answered 13/2, 2019 at 20:54 Comment(6)
Do these changes work for you: capp-sysware.com/misc/stackoverflow/54679254/pm.asmZalea
I made a change to the code.Found I could get the effect I wanted with fword modifier rather than a db 66hZalea
I assume that use32 does the same that .code32 does in the GNU assembler. In this case the location of the first use32 is wrong: The CPU will execute all code in use16 mode up to the jmp far instruction. It will begin executing code in use32 mode AFTER the jmp far instruction. By using use32 before an instruction that is executed in use16 mode, the assembler will generate wrong code.Wheezy
In addition to the other suggestions here, I suggest not putting any code between the move to cr0 and the far jump. It's not wrong, but it can cause confusion, and there's no reason not to put it before the cr0 change.Linin
@Linin Among other things I did move the code between the Protected mode bit set and the JMP.. As well I also turrned off itnerrupts before heading to protected mode. There was an errant use32 for 16-bit encoding present, and the FWORD modifier. also notable was the jmp $ in protected mode so the processor doesn't keep running non-code. Lastly the DS selectorwasn't set once in protected mode before accessing memory with an implicit DS.Zalea
Thanks. Now I can switch to Protected Mode from DOS not using DPMI.Brunhild
L
2

After setting PE (bit 0 of CR0), the processor is running in 16-bit protected mode. The far jump to a 32-bit code segment is the step that causes the processor to start executing in 32-bit mode. Thus the far jump instruction in this code is executed in 16-bit mode, and uses a 16-bit operand by default.

Applying the fword attribute to the instruction operand, as Michael advised, causes the assembler to put an operand size prefix on the far jump instruction, changing the operand size for that instruction to 32 bits.

Another alternative is to change the dd at the far_jump label to dw and continue to use a 16-bit far jump instruction, but only if you know that the 32-bit entry point is within the first 64k of memory. Since the BIOS loads the boot sector at 7c00, this is typically true.

Linin answered 14/2, 2019 at 11:12 Comment(1)
Since this is DOS (and not a bootloader) it is very likely that the computed physical address for the FAR JMP will be above the 64KiB mark. It was in my version of DOSBox. After DOS is loaded the bootloader has likely been all but wiped out. The OP did mention DOSBox, and the format is DOS MZ according to the top of the source code. I've put other conments about what was wrong with the code under the question.Zalea

© 2022 - 2024 — McMap. All rights reserved.