3

基本上,我需要知道从 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 也不起作用。是否有用于返回指针的寄存器?还是像推到堆栈上一样?

4

3 回答 3

7

这不是编写内联汇编的有效方法。即使您将返回值放在正确的寄存器中,它也可能在函数实际返回时丢失/破坏,因为编译器可以添加任意结尾代码。您必须使用输出约束和return语句来返回内联 asm 的结果:

void* kmalloc(unsigned int size)
{
    void *p;
    asm("int $0x80" : "=a"(p) : "S"(size), "a"(9));
    return p;
}
于 2013-01-21T21:01:25.140 回答
4

测试代码:

void * myfunc(void) { return (void *) 0x20341022; }

编译(带gcc --save-temps -O2 -c test.c)为:

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

答案很明显。

于 2013-01-21T20:24:12.947 回答
1

您应该声明内联汇编代码如何使用输出约束返回结果,如下所示:

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变量 equals EAX,因此不需要在堆栈上分配。

于 2013-01-21T21:11:02.947 回答