含多函数调用的函数序言解析:子函数调用是否会破坏栈变量?
栈变量与子函数调用的安全性问题
咱们先看你给出的这个单函数汇编示例:
first_function: pushq %rbp movq %rsp, %rbp movq $2, -8(%rbp) movq $4, -16(%rbp) ... pop %rbp ret
在...执行前用GDB查看栈的结果是:
x/4g $rbp-16
0x7fffffffe410: 0x0000000000000004 0x0000000000000002
0x7fffffffe420: 0x0000000000000000 0x00000000004000bd
你习惯的栈结构可视化也很清晰:
+----------------+--------------------+---------------------------+ | 0x7fffffffe420 | 0x00000000004000bd | # function return address | +----------------+--------------------+---------------------------+ | 0x7fffffffe418 | 0x0000000000000000 | # from push %rbp | +----------------+--------------------+---------------------------+ | 0x7fffffffe410 | 0x0000000000000002 | # from mov $2, -8(%rbp) | +----------------+--------------------+---------------------------+ | 0x7fffffffe408 | 0x0000000000000004 | # from mov $4, -16(%rbp) | +----------------+--------------------+---------------------------+
关于子函数调用是否会破坏栈变量的问题
放心哈,正常情况下完全不会,给你拆解下原因:
- 在x86-64的标准调用约定(System V AMD64 ABI)里,子函数会严格维护自己的栈帧:调用子函数时,会先把返回地址压栈,然后子函数自己会
push %rbp保存当前的rbp,再把rsp指向自己的栈帧起始位置。所有子函数的局部变量、临时数据都会存在自己的栈帧区域里,根本碰不到你在first_function里用-8(%rbp)和-16(%rbp)存的2和4。 - 只有两种极端情况可能出问题:一是子函数本身有栈溢出漏洞,写数据的时候越界写到了你的栈帧区域;二是你写的子函数汇编不遵守调用规范,比如手动修改了rbp或者直接访问调用者的栈帧位置。但只要是正常编译出来的或者符合规范的子函数,绝对不会破坏你的变量。
总结一下:只要调用的是遵循标准约定的子函数,你存在栈里的这两个变量就安安全全的~
内容的提问来源于stack exchange,提问作者David542
相关产品推荐
相关产品推荐

