This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: inline assembly and segment registers
- From: Mihai DonÈu <mihai dot dontu at gmail dot com>
- To: gcc-help at gcc dot gnu dot org
- Date: Fri, 21 Dec 2007 01:37:31 +0200
- Subject: Re: inline assembly and segment registers
- References: <200712202203.41537.mihai.dontu@gmail.com>
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