Page 1 of 1

Inline Assembly & C Question - Concerning Variables

Posted: Thu Apr 27, 2006 3:00 pm
by SteveB
Hi.

I know this isn't the best place to put this but I thought I'd put it here since this is related to OS development for me.

What I want to do, for example, is move the information from eax into a variable defined in C. How would I do this properly? Basically what I want to do is move data from a register into a C variable.

I've tried several ways which were messy since I don't grasp the GCC inline syntax very well. The times I tried and got the C file to compile, it failed when I linked them into the bin.

Thank you,

- Steve

Re:Inline Assembly & C Question - Concerning Variables

Posted: Thu Apr 27, 2006 3:13 pm
by paulbarker
Take a look at the GCC manual (the best place is online at http://gcc.gnu.org/ ). You need to learn about how the constraints operate, but heres a trick. Do a 'nop' with your variable loaded from eax as an output:

Code: Select all

asm volatile ("nop": "=a" (dest)::)
This is a very quick idea, the code above is probably wrong in terms of the letter after the "=" and the number of colons between the nop and the =, but the general idea should be right. Please check this against the manual before trying it.

Re:Inline Assembly & C Question - Concerning Variables

Posted: Thu Apr 27, 2006 7:55 pm
by proxy
what i do for these situations is define a set of ASM fucntions with C interfaces that fit the form:

uint32_t get_eax(void); for each register

they look like this: (a few examples)

Code: Select all

get_eip:
   mov (%esp), %eax
   ret

get_eax:
   ret

get_ebx:
   mov %ebx, %eax
   ret
setting is easier as an inline ASM macro:

Code: Select all

#define set_eax(val) do { __asm__ __volatile__ ("mov %0, %%eax" :: "r" (val)); } while(0)
proxy

Re:Inline Assembly & C Question - Concerning Variables

Posted: Fri Apr 28, 2006 6:22 am
by Pype.Clicker
the real question is "what is in eax and why should it be somewhere else ?"

If the data is indeed in eax (or in eax:edx) as the result of a function call, then everything is fine: that's where C expect data to be returned!

e.g.

Code: Select all

global foo
foo: 
    mov eax, 0x12345678
    ret

Code: Select all

unsigned foo(void);
bar() {
   unsigned baz=foo();
   // f is now 0x12345678
}
If you need to access a C variable from ASM code, just make sure you know its linking name (that may be baz, _baz, __baz_Q26kernel depending on your compiler/language/environment. yet 'baz' is typical for linux and _baz for windows). Then

Code: Select all

extern baz
foo:
    mov [baz],eax
    ret
should do it too...

If you're instead trying to support something like "CPUID" from C, i suggest you look at the "Sample Inline Functions" page on the FAQ. It should show you how to access not only EAX, but all the other potential output registers from inlined assembly.