对 %esp 的修改导致 SIGSEGV [英] A modification to %esp cause SIGSEGV

查看:36
本文介绍了对 %esp 的修改导致 SIGSEGV的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时我会在参加编码比赛时使用以下代码来避免堆栈溢出.

Sometimes I use the following code to avoid stack overflow when taking part in coding competition.

int main()
{
  static const int _STACK_SIZE = MAXN*10;
  static int _STACK[_STACK_SIZE*2], _ESP;
  __asm__ __volatile__
  (
      "movl %%esp, %0
" 
      "movl %1, %%esp
":
      "=g"(_ESP):
      "g"(_STACK + _STACK_SIZE):
  );


  // Do Something..


  __asm__ __volatile__
  (  
      "movl %0, %%esp
":
      :
      "g"(_ESP):
  );
}

据我所知,这个 asm 代码备份了 %esp 并将堆栈移动到 _STACK[].

As far as I know, this asm code backups %esp and moves the stack to _STACK[].

我的问题:为什么这段代码会在 x86-64 Linux 服务器上导致 SIGSEGV(它在我自己的 x86 Linux 上运行良好)?以及如何修复它?

My Question: Why this code cause SIGSEGV on a x86-64 Linux Server(It runs well on my own x86 Linux)? And how to fix it?

我猜,也许是因为 %esp 是一个 64 位指针??

I guess, maybe it's because %esp is a 64-bit pointer??

我试图删除 __asm__ __volatile__("movl %0, %%esp ": : "g"(_ESP):); 并且它似乎运行良好?

I tried to delete the __asm__ __volatile__("movl %0, %%esp ": : "g"(_ESP):); and it seems runs well?

推荐答案

这是因为在 x86-64 汇编中修改 32 位寄存器,例如 esp 将相应 64- 的最高 32 位归零位寄存器,在本例中为 rsp.在 x86-64 中,堆栈指针 rsp 是一个 64 位寄存器.

It's because in x86-64 assembly modifying a 32-bit register such as esp zeroes the highest 32 bits of the corresponding 64-bit register, rsp in this case. In x86-64 the stack pointer rsp is a 64-bit register.

x86-64 Linux 总是把堆栈指针放在虚拟地址空间的用户空间范围的顶部附近,例如 0x7ffffffffe6d0,所以它总是在虚拟地址空间的低 32 位之外.RSP 的高半部分为非零且 ESP != RSP.

x86-64 Linux always puts the stack pointer near the top of the user-space range of virtual address space, like 0x7fffffffe6d0 for example, so it's always outside the low 32 bits of virtual address space. The high half of RSP is non-zero and ESP != RSP.

因此,通过修改esp,您使rsp 指向您的程序没有访问权限的地址,从而导致分段错误.在 x86-64 代码中,您通常根本不使用 esp,您应该在 x86- 中将 esp 的所有实例替换为 rsp64码.

So by modifying esp you make rsp point to an address where your program has no access rights, and thus cause a segmentation fault. In x86-64 code you don't normally use esp at all, and you should replace all instances of esp with rsp in your x86-64 code.

这篇关于对 %esp 的修改导致 SIGSEGV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆