gcc inline assembler syntax for ljmp seg:offset

Programming, for all ages and all languages.
Post Reply
sebihepp
Member
Member
Posts: 184
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

gcc inline assembler syntax for ljmp seg:offset

Post by sebihepp »

Dear OSDev Community,

I am currently hanging with my inline assembler line for the long jump. I tried many thinks and googled for hours, but I am still not able to produce something that will compile.

I am in 32bit PMode and setup a new GDT. Now I want to do a far jump to update the CS. Here is what I use:

Code: Select all

#define GDT_CODE32_SEL 0x08
#define GDT_DATA32_SEL 0x10
(...)
	asm volatile (
		"lgdt %0;"
		"ljmp $%1, $1f;"
		"1:"
		"movw %%ax, %%ds;"
		"movw %%ax, %%es;"
		"movw %%ax, %%fs;"
		"movw %%ax, %%gs;"
		"movw %%ax, %%ss;"
		:  
		: "m" (GlobalDescriptorTableDescriptor), "i" (GDT_CODE32_SEL), "ax" (GDT_DATA32_SEL)
		: 
	);
(...)
The compiler error is that there is an undefined reference to "$8" - But the $ should indicate an immediate value. If I try without the $ I get an error "operand mismatch".

Why does GCC think the $8 is a symbol and not an immediate value?

Best regards
Sebi
sebihepp
Member
Member
Posts: 184
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: gcc inline assembler syntax for ljmp seg:offset

Post by sebihepp »

And as soon as I tried one more thing I solved it: The $ sign is too much for the segment. But why?
Octocontrabass
Member
Member
Posts: 5501
Joined: Mon Mar 25, 2013 7:01 pm

Re: gcc inline assembler syntax for ljmp seg:offset

Post by Octocontrabass »

Tokens in the assembler template are replaced with operands formatted according to the constraint you've chosen. You used "i" as the constraint for the code segment selector, so GCC replaces the "%1" token with "$8". Since you wrote "$%1" in the template, you got "$$8", which the assembler interprets as a reference to a symbol called "$8" and not the literal value 8.

The constraint you used for the data segment descriptor is wrong. You used "ax", but GCC interprets that as "a" and "x" separately. The "a" constraint tells GCC it can use EAX, and the "x" constraint tells GCC it can use any SSE register. You probably wanted to use "a" by itself. (Alternatively, use "r" as the constraint and use "%2" instead of "%%ax" so GCC can choose the register.)
Post Reply