This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: inline assembly and segment registers


On Thursday 20 December 2007, you wrote:
> Hi,
> 
> I know this isn't the proper list to ask this, but I'm desperate :)
> 
> Does anyone know why the code below dies with a 'general protection fault'?:
> 
> DWORD __readfsdword( int index )
> {
> 	DWORD v;
> 	
> 	__asm__ __volatile__ (
> 		"mov %%fs:(%1),%0\n"
> 		:"=a"(v)
> 		:"a"(&index)
> 	);
> 
> 	return v;
> }
> 
> or, why does this work:
>     mov %fs:18,%eax
>     ret
> and this doesn't (asm of the C code above):
>     lea 0x4(%esp),%eax
>     mov %fs:(%eax),%eax <-- crash here
>     ret
> 
> gdb -c core bin
> $gdb p *(int*)$eax
> $1 = 18
> 
> I know I'm lacking some basic x86 know-how, but google doesn't want to help me
> with this one.
> 
> Oh, %fs and the LDT entry are all properly set and I prefer a __readfsdword()
> function instead of a macro (because of the type checking and such), so:
> 
> #define __readfsdword( __index ) ({ DWORD v; __asm__ __volatile__ ( "mov %%fs:" #__index ",%0" : "=r"(v) : ); v; })
> 
> will not do :)

Mm, turns out %eax must contain the index not the memory address where the index
is stored (I was mislead by the parenthesis). So:
    mov 0x4(%esp),%eax
    mov %fs:(%eax),%eax
    ret
works just fine :)

Sorry for the noise.

-- 
Mihai DonÈu


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]