How do void * pointers believe in C?
Basically I need to know which void * registers are specified when they return from the C function. I have this code:
void* kmalloc(unsigned int size)
{
asm("mov %[size], %%esi"
: /* no outputs */
: [size] "m" (size)
: "esi");
asm("movl $9, %eax");
asm("int $0x80");
}
which should put the address in EAX. I thought return values ββin C are stored in EAX, but apparently not (oh, and I'm using GCC BTW). I need how to return EAX, register int won't work either due to compiler settings. Is there a register that is used to return pointers? Or is it like pushing onto the stack or something?
This is not a valid way to write inline asm. Even if you put the return value in the right case, it can be lost / knocked out by the time the function actually returns, because the compiler can add arbitrary epilogue code. You must use escaping constraints and operator return
to return inline asm results:
void* kmalloc(unsigned int size)
{
void *p;
asm("int $0x80" : "=a"(p) : "S"(size), "a"(9));
return p;
}
Test code:
void * myfunc(void) { return (void *) 0x20341022; }
Will compile (with gcc --save-temps -O2 -c test.c
):
myfunc:
.LFB0:
.cfi_startproc
movl $540282914, %eax
ret
.cfi_endproc
The answer is obvious.
You have to declare how your inline assembly code returns a result with an output constraint, for example:
void* kmalloc(unsigned int size)
{
void *result;
asm("mov %[size], %%esi\n"
"movl $9, %%eax\n"
"int $0x80"
: "=a" (result)
: [size] "m" (size)
: "esi");
return result;
}
"=a"
tells the compiler to move the content EAX
into the result variable.
Note that I have also grouped all the asm statements in one block, so I only need to specify the I / O for that block, not for each one.
Compiling with gcc -O3 x.cpp -S
will show you the resulting compiled code:
_kmalloc:
Leh_func_begin1:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movl %edi, -4(%rbp)
## InlineAsm Start
mov -4(%rbp), %esi
movl $9, %eax
int $0x80
## InlineAsm End
popq %rbp
ret
Leh_func_end1:
Note that the optimizer indicates that the variable result
is equal EAX
and therefore does not need to be allocated on the stack.