www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Far jump to code segment with D inline assembler

reply "Alexander Panek" <alexander.panek brainsware.org> writes:
Hello,

I am just doing some R&D regarding low level development with D. Due to the
multiboot standard, and the weird things you have to do at bootup on the x86
architecture, one has to perform a far jump to a specific code segment given
as an offset to the prior registered GDT. Now, with nasm/Intel syntax, you
can just do:

/+ ... +/
jmp 0x08:flush

flush:
/+ ... +/

.. in D, my brain tells me, the syntax would theoretically look like this:

void flush ( )

    asm {
        naked;

        /+ ... +/
        jmp int far ptr 0x08:flush;

        flush:
            /+ ... +/

        ret;
    }
}

Yet, the compiler (1.009) yells at me, that either the operand size for
`jmp` is wrong, or it would have expected nops instead of the jump
statement.

Any advice one could give?

Thanks in advance, and best regards,
Alex
Mar 12 2007
next sibling parent "Alexander Panek" <a.panek brainsware.org> writes:
On Tue, 13 Mar 2007 05:24:44 +0100, Alexander Panek  
<alexander.panek brainsware.org> wrote:
 [...]
 void flush ( )

     asm {
         naked;

         /+ ... +/
         jmp int far ptr 0x08:flush;

         flush:
             /+ ... +/

         ret;
     }
 }
 [...]

Scratch that `int`. It's meant to be a 48-bit address.
Mar 12 2007
prev sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Alexander Panek wrote:
 I am just doing some R&D regarding low level development with D. Due to the
 multiboot standard, and the weird things you have to do at bootup on the x86
 architecture, one has to perform a far jump to a specific code segment given
 as an offset to the prior registered GDT.

This doesn't have much to do with the multiboot standard, just the x86 architecture. Multiboot just doesn't allow you to assume the GDT is already correctly loaded (though the segment registers will be).
 Now, with nasm/Intel syntax, you
 can just do:
 
 /+ ... +/
 jmp 0x08:flush
 
 flush:
 /+ ... +/
 
 .. in D, my brain tells me, the syntax would theoretically look like this:
 
 void flush ( )
 
     asm {
         naked;
 
         /+ ... +/
         jmp int far ptr 0x08:flush;
 
         flush:
             /+ ... +/
 
         ret;
     }
 }
 
 Yet, the compiler (1.009) yells at me, that either the operand size for
 `jmp` is wrong, or it would have expected nops instead of the jump
 statement.
 
 Any advice one could give?

Sorry, I have no idea how to do this in the D inline assembler. I just have an external .asm file that sets up the GDT (and rudimentary paging) before calling the D code. I prefer the NASM variation of asm syntax anyway.
Mar 13 2007
parent "Alexander Panek" <a.panek brainsware.org> writes:
On Tue, 13 Mar 2007 11:49:22 +0100, Frits van Bommel  
<fvbommel REMwOVExCAPSs.nl> wrote:
 This doesn't have much to do with the multiboot standard, just the x86  
 architecture. Multiboot just doesn't allow you to assume the GDT is  
 already correctly loaded (though the segment registers will be).

Yea, I've seen that after the second time of reading, too. X-P
 Sorry, I have no idea how to do this in the D inline assembler. I just  
 have an external .asm file that sets up the GDT (and rudimentary paging)  
 before calling the D code. I prefer the NASM variation of asm syntax  
 anyway.

I do have an assembler file for exactly that, which I just try to translate to D code.
Mar 13 2007