初学者内联汇编分段错误

时间:2013-11-18 05:05:20

标签: c assembly x86 segmentation-fault inline-assembly

我第一次写Inline程序集,我不知道为什么当我尝试运行它时会出现Seg故障。

#include <stdio.h>
int very_fast_function(int i){
    asm volatile("movl %%eax,%%ebx;"
        "sall $6,%%ebx;"
        "addl $1,%%ebx;"
        "cmpl $1024,%%ebx;"
        "jle Return;"
        "addl $1,%%eax;"
        "jmp End;"
        "Return: movl $0,%%eax;"
        "End: ret;": "=eax" (i) : "eax" (i) : "eax", "ebx" );
    return i;
    /*if ( (i*64 +1) > 1024) return ++i;
    else return 0;*/
}

int main(int argc, char *argv[])
{
    int i;
    i=40;
    printf("The function value of  i is %d\n", very_fast_function(i));
    return 0;
}

就像我说这是我的第一次,所以如果它非常明显我道歉。

2 个答案:

答案 0 :(得分:1)

您不得直接使用ret。原因:在进入每个函数时都有像堆栈一样的初始化或保存帧指针,也有相应的终结。如果直接使用ret,则只是不保留堆栈。

只需删除ret,就不会出现分段错误。

但是我想结果并不像预期的那样。原因是您的输入/输出约束不符合预期。请注意,您撰写的"=eax" (i)未指定使用%%eax作为i的输出,而是表示应用约束e a和{{1}输出变量x

出于您的目的,您只需使用i来指定注册表。请参阅我刚刚测试过的这个编辑过的代码:

r

此处要明确使用asm volatile("movl %1,%%ebx;" "sall $6,%%ebx;" "addl $1,%%ebx;" "cmpl $1024,%%ebx;" "jle Return;" "addl $1,%0;" "jmp End;" "Return: movl $0,%0;" "End: ;": "=r" (i) : "r" (i) : "ebx" ); ,请使用%%eax代替"=a"

有关详细信息,请阅读此http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

答案 1 :(得分:0)

不应在内联汇编块中使用

ret - 您所处理的函数需要进行一些简单的ret处理之外的清理。

请记住,内联汇编直接插入到它嵌入的函数中。它本身并不是一个函数。