当前位置: 技术问答>linux和unix
怎么没人进呢?请高手进来看一下吧,你应该不会后悔进的,虽然标题写的不吸引人。所以把原标题去了
来源: 互联网 发布时间:2017-02-07
本文导语: 本帖最后由 mjznet 于 2011-09-28 18:13:23 编辑 就是这段代码在linux下可编译通过,但执行时收到段错误信号。SIGSEGV 但在win下用相同的逻辑重写这段代码是ok的。 这段代码是用来测试ljmp 功能的,为什么不行呢? 望高手不...
但在win下用相同的逻辑重写这段代码是ok的。
这段代码是用来测试ljmp 功能的,为什么不行呢? 望高手不吝赐教,万分感谢!
int main()
{
unsigned long a[2] = {0,0};
__asm__("push 1f;"
"popl %0;"
"push %%cs;"
"popl %1;"
"andl $0x000000ff,%1;" /*改成 "andl $0x0000ffff,%1;" 仍然不行*/
"ljmp *%2;"
"1:"
:"=m" (a[0]), "=m" (a[1])
:"m" (*(char*)&a[0]));
return 0;
}
|
因为你在"push 1f"压入的不是1:这个地址,而是1:这个地址上所存放的内容,也就是return 0;代码翻译成的指令mov $0x0, %eax,也就是b8 00 00 00 00。
所以在a[0]中存放的就是0x000000b8,所以最后ljmp时总是试图跳转到0x000000b8这个地址去,所以一定会SIGSEGV错误。
这完全是gcc内嵌汇编的问题,你在windows下写的时候不出错也很正常。
要改正的话,只需要把"push 1f;"改为"push $1f;"即可。
另外,gcc内嵌汇编一般分隔指令会用"push $1fn"的形式,这样在看汇编出来的代码时会规整很多。
所以在a[0]中存放的就是0x000000b8,所以最后ljmp时总是试图跳转到0x000000b8这个地址去,所以一定会SIGSEGV错误。
这完全是gcc内嵌汇编的问题,你在windows下写的时候不出错也很正常。
要改正的话,只需要把"push 1f;"改为"push $1f;"即可。
另外,gcc内嵌汇编一般分隔指令会用"push $1fn"的形式,这样在看汇编出来的代码时会规整很多。
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。