News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Global Descriptor Table

Started by MaxPayne, May 23, 2005, 11:13:23 PM

Previous topic - Next topic

MaxPayne

But when I run it clear after power on (after POST) there is no memory managers loaded ?  Am i right ?

AeroASM

No, there aren't.

memory managers are loaded by the operating system such as Windows or MS-DOS. Therefore to make sure they are not loaded, either load Win9x ms-dos safe mode or make your own OS.

MaxPayne

I'm sure - because i run it after POST. I mean that my bootloader execute all this. Bootloader is ok - i check it

MaxPayne

I've check it once again.. and there is something streange.. this program fail o this instructions:
...
       cli
       mov eax,cr0
       or eax,01h
       mov cr0,eax
       sti
...
lgdt is allright... but why it crush enterin in pmode?? eaven gdt is wrong it should works, because lgdt doesn't change any segments.. only we have to make a far jmp or retf... strange

Greetings

MaxPayne

AeroASM

Just remembered something:

Straightaway after mov cr0,eax you must make the far jump, to do two things:

1. Make the cs register point to a valid segment (probably 0008)
2. Flush the prefetch queue.

Straightaway after the jump you should (not must) set all segment selectors (cs,ds,es,fs,gs,ss) to either a valid segment or 0 (null segment).

When I was making an OS it kept failing... eventually I discovered it was because I had put 16h not 16 into a selector!

MaxPayne

Offtopic: Aero are You realy 14 years old ??

Max

AeroASM

Actually about 14.3

Why do you ask?

MaxPayne

When I was 14, i have only know that ther is something like asm.. nothing more :)

Max

MichaelW

Max,

I added the comment on the 386 memory managers because it was not unusual for Windows 9x systems to be running one of these managers for MS-DOS mode. Windows 9x (and the later versions of MS-DOS) included the Microsoft 386 memory manager EMM386.EXE.

A far (inter-segment) jump after the mode switch was necessary for the 386 and 486 to empty the prefetch queue and load the CS descriptor cache. Starting with the Pentium there was no need to empty a prefetch queue, but a far jump is still a reasonable method of loading the CS descriptor cache. AFAIK, unless you have an IDT and the necessary handlers in place, you should not enable interrupts after the mode switch.

Judging from Aero's posts, I too would expect someone older that 14.3 :)


eschew obfuscation

MaxPayne

Hi MichaelW !

Thank You for that info. Please correct me if  i'm wrong:

This is my gdt
    gdt_descr:
       dw 3*8-1
       dd offset gdt
    gdt:
      dd 0,0 ; NULL Descriptor
      dd 00000FFFFh,000CF9A00h
      dd 00000FFFFh,000CF9200h

and when i do something like this:

                ....
                lgdt fword ptr gdt_descr
                cli      
   mov eax,cr0
   or eax,01h
   mov cr0,eax

               jmp far pmode ; or db   0eah 
                                    ; dw offset pmode

               pmode:
               ... ;32bit prtoected mode code

What will be in my CS register ?? will it be 0001h - selector ??? Will cpu execute code after pmode: label ??If i want cpu to execute further my code - after pmode: label - what sould i do ?? When i run this code in VMware, it makes "Virtual machine kernel stack fault (hardware reset)..."


Greetings


MichaelW

#25
You need to specify the selector and the offset address in the jump instruction. Something like this:

db 0eah
dw offset pmode
dw 8
pmode:

I don't know what kind of segment structure you are using for the real-mode code, but note that this will assemble only if the default address size for the current segment is 16 bits.

Note also that the offset address is encoded as an absolute value rather than a displacement (a relative address). To make this work, you need to ensure that the segment base specified in the code segment descriptor matches the segment base for the segment of the jump instruction, or you need to adjust the offset address to compensate for the difference in the bases.

In my previous post read "load the CS descriptor cache" as "load the code selector into CS". Loading the code selector into CS will cause the processor to load the CS descriptor cache, but your code is just loading the selector into CS.

If your protected mode code uses data, you will need to load a valid selector into DS. If your protected mode code uses the stack, you will need to load a valid selector into SS and set ESP to a useable value.

If you get everything right, then you program should be able to execute in protected mode. But once you are in protected mode you will not be able to call the BIOS functions, so to display anything (without complex code) you will need to write it directly to the display buffer. If your data segment overlaps the display buffer, you could calculate the necessary offset addresses from the segment base and the absolute address of the display buffer. But it would probably be easier to create a segment descriptor for the display buffer (with the base set to B8000h), load the corresponding selector into ES, and access the display buffer using an ES segment override and the normal offset addresses.

Agner Fog has some test programs that switch to protected mode, perform the tests, and then switch back to real mode. You may be able to learn something useful by studying the source.

http://www.agner.org/assem/
eschew obfuscation