flat assembler
Message board for the users of flat assembler.

Index > OS Construction > 64 bit to 32 bit jmp problem,

Author
Thread Post new topic Reply to topic
lazer1



Joined: 24 Jan 2006
Posts: 185
lazer1 15 Apr 2006, 16:19
I'm experimenting with 64 bit code, without interrupts,

I'm trying to switch from long mode to
compatibility mode by jumping via the gdt,

I get error messages from fasm when I try this,
what is the correct way to do the jmp? Rolling Eyes


the code fragment is:

Code:
                org 10000h

use16

         ; lots of code here to reach 64 bit,


use64
        
        jmp pword gdt.code32-gdt:trick32 ;  Confused 

use32

trick32:

        ; .........

;============================ GDT ===============================

gdt:

;=============== NULL segment ==============

.null   dd      0
        dd      0

;=========== code32 ==================

.code32:
        dw      0ffffh
        dw      0h
        db      0
        db      10011110b
        db      11001111b
        db      0

;=========================================================

;...........

    


Last edited by lazer1 on 19 Apr 2006, 02:15; edited 1 time in total
Post 15 Apr 2006, 16:19
View user's profile Send private message Reply with quote
OS ?



Joined: 18 Apr 2006
Posts: 1
OS ? 18 Apr 2006, 21:33
Hi lazer1 Smile
Just a guess but I think you need to look into page translation?
Post 18 Apr 2006, 21:33
View user's profile Send private message Reply with quote
MAD_DËMON



Joined: 03 Mar 2006
Posts: 23
MAD_DËMON 19 Apr 2006, 00:24
I think that you need to disable Long Mode Active Bit from the EFER MSR and load the 32 bit legacy GDT before make the jump that transfer the control to a 32 bit pmode

Code:
org 10000h



use64

        lgdt [gdt]

        jmp far 2:trick32 ; Selector Index 1 : Trick 32

use32 

trick32: 

        ; ......... 

;============================ GDT =============================== 

gdt: 

;=============== NULL segment ============== 

.null   dd      0 
        dd      0 

;=========== code32 ================== 

.code32: 
        dw      0ffffh 
        dw      0h 
        db      0 
        db      10011110b 
        db      11001111b 
        db      0 

;========================================================= 

;...........     


if it not work then look to the AMD or Intel system programming manuals I think that it can be do making a "Compatibility Mode/Legacy" Code Descriptor in a 64 bit GDT

_________________
Tah rah rah boom de ay, I blew some guy away, his brains turned into spray, I was paid well that day
Post 19 Apr 2006, 00:24
View user's profile Send private message Visit poster's website Reply with quote
lazer1



Joined: 24 Jan 2006
Posts: 185
lazer1 19 Apr 2006, 02:17
OS ? wrote:
Hi lazer1 Smile
Just a guess but I think you need to look into page translation?


Hi,

the above code fragment omits all the stuff to reach 64 bit, Razz

I've modified it now so you see what I mean,

the question was a compilation question, that fasm
doesnt compile the fragment I gave,
Post 19 Apr 2006, 02:17
View user's profile Send private message Reply with quote
lazer1



Joined: 24 Jan 2006
Posts: 185
lazer1 19 Apr 2006, 02:34
MAD_DËMON wrote:
I think that you need to disable Long Mode Active Bit from the EFER MSR and load the 32 bit legacy GDT before make the jump that transfer the control to a 32 bit pmode


Hi,

see other reply,

the question was not a run time question but a
compile time question,

the fragment I gave clearly wont run, however
it should compile, at least I'm asking what modification
of it will compile,

I've just tried "far" instead of "pword" and it also
doesnt compile,

Note that its not 2:some_offset but 2 * 8 : some_offset,

and its not in fact 2 but 1 so its
8:some_offset as the GDT index is shifted left 3 bits,

ie the GDT index is literally the offset into the GDT table,

gdt.code64-gdt achieves this, :useful trick,

ie gdt.code64-gdt:some_offset is

(index shl 3):some_offset,

Quote:
... making a "Compatibility Mode/Legacy" Code Descriptor in a 64 bit GDT


you dont need a 64 bit GDT, 64 bit segment descriptors can be
put in a 32 bit GDT,

thats a useful feature of AMD's design that you dont need a new GDT,

and note that 64 bit uses virtually no segment descriptors,
and if you try loading ds with one the machine resets,

fs and gs are 64 bit in long mode and you load + read them with
a msr fs.base and gs.base, ie you dont use the GDT,

the GDT is only used for things like switching to compatibility mode
and loading the IDT and TR,

however I think you do need a new 64 bit IDT, I've not got as
far as interrupts yet,

long mode is basically an unsegmented architecture,

segments are only used mainly to enter and leave long mode,

once you are in long mode you dont use segments,
which is really great because I hate segments! Very Happy

long mode is always full flat addressing,

also long mode has extra 64 bit registers: R8, R9, R10, R11, R12, R13,
R14, R15, Razz Very Happy Smile Surprised Laughing Wink Twisted Evil Idea

not just rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
Evil or Very Mad Mad Sad Embarassed Crying or Very sad Confused Arrow Question
but you get an extra 8 new GPRs,

I've tried a few things with long mode and it is fantastic,
eg I set up gs with a 64 bit value, 00000000000B8000h
via the msr,
and wrote to the screen successfully with this,
Rolling Eyes
Post 19 Apr 2006, 02:34
View user's profile Send private message Reply with quote
fonolite



Joined: 14 Dec 2005
Posts: 32
fonolite 19 Apr 2006, 06:45
jmp to compatibility mode is not the change of modes.
It's just a jump between 32bit and 64bit segment.
You always should keep EFER.LMA=1 active.


This is my code about jmp to 32bit segment.

Code:
jmp far pword [@F]
@@:
 dd Trick32
 dd gdt.code32-gdt ; .code32-gdt value    


This is indirect jmp far to selector32:offset32



I remember long mode doesn't allow direct jmp as follows.

Code:
jmp far pword gdt.code32-gdt:trick32    

(anyway compiled OK.)
Post 19 Apr 2006, 06:45
View user's profile Send private message Reply with quote
lazer1



Joined: 24 Jan 2006
Posts: 185
lazer1 20 Apr 2006, 14:46
Hi fonolite,

your code fragment is excellent Razz

it answers the question exactly

and the anonymous label trick is a
very clean way to keep the code readable,

fonolite wrote:
jmp to compatibility mode is not the change of modes.
It's just a jump between 32bit and 64bit segment.
You always should keep EFER.LMA=1 active.


technically its just a jmp or a call through the GDT,

so its not even supervisor level (I think),

it is as powerful as a mode change but isnt a mode change,



Quote:

This is my code about jmp to 32bit segment.

Code:
jmp far pword [@F]
@@:
 dd Trick32
 dd gdt.code32-gdt ; .code32-gdt value    


This is indirect jmp far to selector32:offset32


that answers the original question superbly Very Happy

Quote:

I remember long mode doesn't allow direct jmp as follows.

Code:
jmp far pword gdt.code32-gdt:trick32    

(anyway compiled OK.)


with long mode if you do something which would be
correct in other modes and it compiles then it
tends to be correct in long mode,

so far all 64 bit code I've tried that fasm accepts
also runs correctly. Cool

interrupts are switched off via cli and I cannot
access most of ram as the MMU tree is almost empty.
Also I switched off all caching to make sure the
gfx mem is uncached. I have just enough set up
to experiment with things. I dont have any useful
code yet and wrote text by hacking it directly:

Code:
                .....
use64
                ....
        ; CPL==0 only: FS.base msr @ is c000_0100h, gs.base msr is c000_0101
        mov ecx,0c0000101h      ; gs.base
        mov edx,0
        mov eax,0b8000h
        wrmsr   ; edx:eax to msr(ecx)

        mov [gs:0h], byte 'H'
        mov [gs:1h], byte 1111001b
        mov [gs:2h], byte 'A'
        mov [gs:3h], byte 1111010b

        mov [gs:4h], byte 'H'
        mov [gs:5h], byte 1111100b
        mov [gs:6h], byte 'A'
        mov [gs:7h], byte 11111b

        mov [gs:8h], byte 'H'
        mov [gs:9h], byte 101111b
        mov [gs:0ah], byte 'A'
        mov [gs:0bh], byte 1001111b
        
.rpt:   jmp .rpt

    


the above functioned correctly echoing HAHAHA to the screen,

all my 80x25 text code is in 16 bit real so I cannot use it,

it will require some work before I know for sure,
but I am confident about your code fragment,

I want to try and revert to real mode from long mode as
that looks like an interesting problem! Smile

once I reach real mode then I'll switch on interrupts
and I can use the BIOS, Surprised
Post 20 Apr 2006, 14:46
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.