[英]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.