You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NASM x86-64栈安全赋值方法及[rbp-16]地址访问疑问

在NASM x86-64中栈空间的分配与访问逻辑

要搞懂这个问题,核心是先明确x86-64架构下栈的向下增长特性:栈的地址从高到低变化——分配栈空间时RSP(栈指针)减小,释放时RSP增大。

我们一步步拆解你给出的代码,看栈空间的实际布局:

  1. 栈帧序言

    • push rbp:将旧的基址指针rbp压入栈,此时RSP = RSP - 8,栈顶地址就是当前RSP,存储着旧rbp的值。
    • mov rbp, rsp:让rbp指向当前栈顶,此时rbp与RSP值相等,[rbp]就是刚才压入的旧rbp。
    • sub rsp, 16:分配16字节栈空间,此时RSP = rbp - 16。这一步完成后,可用栈空间范围是**rbp-16(当前RSP)到rbp-1**,共16字节。
  2. 栈空间访问

    • mov [rbp - 8], rdi:rbp-8处于rbp-16到rbp之间,属于刚分配的16字节空间,用来存储rdi的8字节值。
    • mov [rbp - 16], rsi:rbp-16就是当前RSP的地址,完全在分配的16字节范围内,用来存储rsi的8字节值。

你疑惑的点源于对“RSP指向最后分配栈元素的末尾”的误解——这个说法不准确:

  • 用push压入元素时,RSP先减8,再将数据存入RSP指向的地址,此时RSP指向刚压入元素的起始地址。
  • 用sub rsp, n分配栈空间时,RSP直接减n,此时RSP指向分配的n字节空间的最低地址,这个地址及更高地址(直到RSP + n - 1,即rbp-1)都是合法可访问区域。

所以访问[rbp-16]完全符合栈空间使用规则,没有越界。

  1. 栈帧尾声
    • add rsp, 16:将RSP恢复到rbp位置,释放之前分配的16字节空间。
    • pop rbp:弹出旧rbp,恢复基址指针。
    • ret:返回调用者,弹出栈上的返回地址。

内容的提问来源于stack exchange,提问作者kvlihidden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 08:03:22