Ljmp syntax in gcc inline assembly

assemblygnu-assemblerinline-assemblysegments

I was thinking of using a far jump to set the code segment (CS) register. Getting into why I'm doing this and why I'm dealing with segmentation at all would take a while, so bear with me and consider it an academic exercise. I can't seem to get the syntax right.

Error: suffix or operands invalid for 'ljmp'

I know it's foolish to put cs into another register, but I figured I'd try it since using %0 wasn't working (the ax register doesn't work either).

I'm looking at some code that compiles fine and this is driving me crazy, since I thought ljmp would be the same: __asm volatile ( "lcall $0x8, $far_call" );

I would of course welcome other hacky ways of affecting the CS register.

void set_cs(u16 cs) {
    __asm__ volatile (
        "mov %0, %%ax \n\t"
        "ljmp %%ax, $fake_label \n\t"
        "fake_label: \n\t"
        :
        : "r" (cs)
        : "ax"
    );
}

Best Solution

It would appear ljmp requires constants to work, while this generates more code and is obviously not particularly safe, this appears to work as when I enter a value that is not the current cs value, the application crashes. It uses an immediate value instead:

#define set_cs( cs ) asm volatile ( "ljmp %0, $fake_label \n\t fake_label: \n\t" :: "i"(cs) )

It's not as elegant as I assume you wanted it to be, and depends entirely on what you're trying to do. I can't imagine this ever being useful or even working if you're compiling this to run under linux/windows.