简体   繁体   English

如何在C中返回void *指针?

[英]How are void* pointers returned in C?

Basically I need to know what register void* pointers are placed in when they are returned from a C function. 基本上我需要知道从C函数返回时寄存器void *指针的位置。 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 an address into EAX. 应该将地址放入EAX。 I thought that return values in C were stored in EAX, but apparently not, (oh and I am using GCC BTW). 我认为C中的返回值存储在EAX中,但显然不是,(哦,我正在使用GCC BTW)。 I need to some how return EAX, register int won't work either because of the compiler settings. 我需要一些如何返回EAX,寄存器int将无法工作,因为编译器设置。 Is there a register that is used for returning pointers? 是否有用于返回指针的寄存器? Or is it like pushed onto the stack or something? 或者它是否像被推入堆栈或什么?

This is not a valid way to write inline asm. 这不是编写内联asm的有效方法。 Even if you put the return value in the right register, it could be lost/clobbered by the time the function actually returns, because the compiler can add arbitrary epilogue code. 即使您将返回值放在正确的寄存器中,它也可能在函数实际返回时丢失/破坏,因为编译器可以添加任意的结尾代码。 You must use output constraints and a return statement to return the results of inline asm: 您必须使用输出约束和return语句来返回内联asm的结果:

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; }

Compiles (with gcc --save-temps -O2 -c test.c ) to: 编译(使用gcc --save-temps -O2 -c test.c ):

myfunc:
.LFB0:
    .cfi_startproc
    movl    $540282914, %eax
    ret
    .cfi_endproc

Answer is obvious. 答案很明显。

You should declare how your inline assembly code returns it's result with an output constraint, like this: 您应该声明内联汇编代码如何使用输出约束返回结果,如下所示:

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;
}

The "=a" tells the compiler to move the contents of EAX to the result variable. "=a"告诉编译器将EAX的内容移动到结果变量。

Note that i also grouped all the asm statements in one block, this way i only need to specify the input/output for this block, instead of for each statement by itself. 请注意,我还将所有asm语句分组到一个块中,这样我只需要为此块指定输入/输出,而不是为每个语句指定它自己。

Compiling this with gcc -O3 x.cpp -S will show you the resulting compiled code: 使用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:

Note that the optimizer figures out that the result variable equals EAX , and thus does not need to be allocated on the stack. 请注意,优化器会发现result变量等于EAX ,因此不需要在堆栈上分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM