【问题标题】:indirect access of stack failed间接访问堆栈失败
【发布时间】:2020-05-21 18:02:43
【问题描述】:

我刚开始学习 intel att 汇编,遇到了下一个问题:当我尝试使用访问堆栈时出现段错误。我确实间接访问了内存位置,但是当我尝试使用堆栈这样做时,我得到了段错误。我的系统是:

Linux cat 4.19.36 #1-NixOS SMP Sat Apr 20 07:16:05 UTC 2019 x86_64 GNU/Linux

我使用气体编译器:

  as -gfstab  -o a.o a.s
  ld -o a.out a.o

这是我的小代码示例:

.code64
.globl _start
.text

_start:  
  movl (%esp) , %eax

  xor %eax , %eax
  inc %eax
  int $0x80

程序已编译并链接,但当我尝试启动它时,我得到了:

as -gfstab  -o a.o a.s
ld -o a.out a.o
./a.out 
make: *** [makefile:4: new] Segmentation fault

我使用 gdb 来解决这个问题。间接访问堆栈给了我下一个结果:

6   movl (%esp) , %eax
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
_start () at a.s:6
6   movl (%esp) , %eax

我从互联网上拿了这个例子,他们说这是做事的方式。我做错了什么? TNX

【问题讨论】:

  • 您创建了一个 64 位程序,但尝试使用 32 位地址。要么制作一个 32 位程序,要么重写代码以使用 64 位地址。
  • 谢谢!我只用 rax 和 rsp 重写它,它现在可以工作了! tnx

标签: assembly x86


【解决方案1】:

已解决!

问题在于,当您处于 x64 模式时,您必须使用 %r.. 寄存器来处理堆栈。就这些

所以实际的代码是这样的:

.code64
.globl _start
.text

_start :  

  push $5 
  push $3
  push $2
  call myproc 
  add $24 , %rsp

  xor %rax , %rax
  inc %rax
  int $0x80

myproc :

  mov  8 (%rsp) , %rbx
  mov 16 (%rsp) , %rax
  add %rax , %rbx
  mov 24 (%rsp) , %rax
  add %rax , %rbx
  ret

tnx Jester 为您提供帮助

【讨论】:

  • 64 位代码的标准调用约定传递寄存器中的前 6 个整数参数,仅使用第 7 个和更高版本的堆栈。但是,是的,您应该使用 64 位寻址模式,并且需要使用不适合 32 位的指针。而且这个例子的低效自定义调用约定确实演示了使用堆栈。
  • 另请注意,mov $1, %eax 的长度为 5 个字节,比xor %rax,%rax(3 个字节including wasted REX prefix)加上inc %rax(3 个字节)更小且更高效。更重要的是,不要在 64 位代码中使用int $0x80What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-18
  • 2022-01-01
  • 2017-11-22
  • 2015-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多