怎么没人进呢?请高手进来看一下吧,你应该不会后悔进的,虽然标题写的不吸引人。所以把原标题去了
就是这段代码在linux下可编译通过,但执行时收到段错误信号。SIGSEGV
但在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 $1f\n"的形式,这样在看汇编出来的代码时会规整很多。