热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

为什么在这段汇编代码中调用“pop”会导致分段错误?

如何解决《为什么在这段汇编代码中调用“pop”会导致分段错误?》经验,为你挑选了1个好方法。

我在Mac OS上玩x86-64程序集(使用NASM 2.09和2.13,以捕获由NASM问题引起的错误)。我目前正在尝试实现函数调用,并尝试使用pushpop指令,但pop始终似乎会导致段错误:

line 10: 41072 Segmentation fault: 11 ./result

我尝试手动调整rsprbp等等,但这pop似乎是问题所在。任何帮助,将不胜感激!

section .data

default rel
global start
section .text

start:
    mov r12, 4
    push r12
    call label_0_print_digit
    (some stuff to exit program)

label_0_print_digit:
    pop r12
    (some stuff to print the digit - the issue persists even without this)
    ret 

prl.. 5

在问题所示的代码中,call指令将返回地址放在堆栈上,pop指令从堆栈中删除返回地址(放入r12)。

ret然后,该指令4从堆栈弹出并跳转到那里。这不是有效的代码地址,从而导致故障。 ret基本上只是pop进入RIP。


访问参数的函数,是在堆栈上,使用[rsp + 8][rsp + 16]而不是等pop

x86-64的标准调用约定在寄存器而不是堆栈中传递整数args,而被调用者可以在其中直接使用它们。并且避免了调用者在函数返回后必须清理堆栈。(有2种:Linux / MacOS / etc与Windows,使用不同的寄存器。)



1> prl..:

在问题所示的代码中,call指令将返回地址放在堆栈上,pop指令从堆栈中删除返回地址(放入r12)。

ret然后,该指令4从堆栈弹出并跳转到那里。这不是有效的代码地址,从而导致故障。 ret基本上只是pop进入RIP。


访问参数的函数,是在堆栈上,使用[rsp + 8][rsp + 16]而不是等pop

x86-64的标准调用约定在寄存器而不是堆栈中传递整数args,而被调用者可以在其中直接使用它们。并且避免了调用者在函数返回后必须清理堆栈。(有2种:Linux / MacOS / etc与Windows,使用不同的寄存器。)


请注意,调用者然后需要知道函数返回时参数仍在堆栈上。
推荐阅读
author-avatar
cjcstc@163.com
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有