初学者内联汇编分段错误
Posted
技术标签:
【中文标题】初学者内联汇编分段错误【英文标题】:Beginner Inline Assembly Segmentation fault 【发布时间】:2013-11-18 05:05:20 【问题描述】:我是第一次编写内联汇编,但我不知道为什么在尝试运行它时会出现 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;
就像我说的那样,这是我的第一次,所以如果它非常明显,我道歉。
【问题讨论】:
看看setg指令。如果你在开始时清空 eax,在 cmpl 之后你可以执行 setg %al 并完成它。 【参考方案1】:您不得直接使用ret
。原因:在进入每个函数的时候有压栈或者保存帧指针的初始化,也有相应的finalization。如果直接使用ret
,你只是让堆栈不恢复。
只要去掉ret
就不会出现分段错误。
但是我认为结果并不像预期的那样。原因是您的输入/输出约束不符合预期。请注意,您编写的"=eax" (i)
没有指定使用%%eax
作为i
的输出,而这意味着在输出变量i
上应用约束e
a
和x
。
出于您的目的,您可以简单地使用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"
而不是"=r"
。
更多信息,请阅读http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
【讨论】:
太棒了,非常感谢您的帮助!修复一切! @user2926342 总是很高兴能提供帮助:D【参考方案2】:ret
不应在内联汇编块中使用 - 除了简单的 ret
将处理之外,您所使用的函数还需要一些清理。
请记住,内联汇编直接插入到它所嵌入的函数中。它本身并不是一个函数。
【讨论】:
以上是关于初学者内联汇编分段错误的主要内容,如果未能解决你的问题,请参考以下文章