Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
913 views
in Technique[技术] by (71.8m points)

linux - A modification to %esp cause 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):
  );
}

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


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?

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

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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 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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...