[英]How are void* pointers returned in C?
基本上我需要知道从C函数返回时寄存器void *指针的位置。 我有这个代码:
void* kmalloc(unsigned int size)
{
asm("mov %[size], %%esi"
: /* no outputs */
: [size] "m" (size)
: "esi");
asm("movl $9, %eax");
asm("int $0x80");
}
应该将地址放入EAX。 我认为C中的返回值存储在EAX中,但显然不是,(哦,我正在使用GCC BTW)。 我需要一些如何返回EAX,寄存器int将无法工作,因为编译器设置。 是否有用于返回指针的寄存器? 或者它是否像被推入堆栈或什么?
这不是编写内联asm的有效方法。 即使您将返回值放在正确的寄存器中,它也可能在函数实际返回时丢失/破坏,因为编译器可以添加任意的结尾代码。 您必须使用输出约束和return
语句来返回内联asm的结果:
void* kmalloc(unsigned int size)
{
void *p;
asm("int $0x80" : "=a"(p) : "S"(size), "a"(9));
return p;
}
测试代码:
void * myfunc(void) { return (void *) 0x20341022; }
编译(使用gcc --save-temps -O2 -c test.c
):
myfunc:
.LFB0:
.cfi_startproc
movl $540282914, %eax
ret
.cfi_endproc
答案很明显。
您应该声明内联汇编代码如何使用输出约束返回结果,如下所示:
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"
告诉编译器将EAX
的内容移动到结果变量。
请注意,我还将所有asm语句分组到一个块中,这样我只需要为此块指定输入/输出,而不是为每个语句指定它自己。
使用gcc -O3 x.cpp -S
编译它将显示生成的编译代码:
_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:
请注意,优化器会发现result
变量等于EAX
,因此不需要在堆栈上分配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.