X86汇编PUSH与POP操作对于变量在内存中高低地址的转换分析

一、高低地址的核心概念

内存可以看作是一段线性的、按字节编号的存储空间,就像一条无限长的街道,每个字节都是一个"房子",每个房子有唯一的"门牌号"(地址):

  • 低地址 :地址数值的内存位置(比如 0x00001000)。
  • 高地址 :地址数值的内存位置(比如 0x00002000)。

举个通俗例子:把内存地址想象成楼层号,低地址是1楼、2楼(数值小),高地址是10楼、20楼(数值大)。

关键特性(x86架构,逆向最常用):

栈的生长方向是从高地址向低地址扩展 ------压栈(push)数据时,栈顶寄存器esp的数值会减小 (指向更低的地址);出栈(pop)数据时,esp数值会增大(指向更高的地址)。

二、结合栈帧的具体地址数值举例

以32位x86系统(逆向最经典场景)为例,用main函数调用add(a=1, b=2)的过程,一步步展示栈地址的变化,所有地址均为十六进制(逆向标准表示)。

前提约定:
  • 32位系统中,每个栈操作(push/pop)占用4字节(地址增减步长为4)。
  • 调用约定为cdecl(C语言默认):参数从右到左入栈,返回地址由call指令保存。
  • 初始状态:main函数的栈帧基址ebp=0x0012FF80(栈帧底部,高地址),esp=0x0012FF80(栈顶,初始与底部重合)。
步骤1:参数入栈(main调用add前)

cdecl约定下,参数从右到左压栈(先压b,再压a):

  1. 压入参数b=2:
    • 执行push 2esp = 0x0012FF80 - 4 = 0x0012FF7C(地址减小,指向更低地址)。
    • 内存地址0x0012FF7C(高地址)存储数值2。
  2. 压入参数a=1:
    • 执行push 1esp = 0x0012FF7C - 4 = 0x0012FF78
    • 内存地址0x0012FF78(低地址)存储数值1。

此时栈地址分布(高→低):

地址(十六进制) 存储内容 说明
0x0012FF7C 2(参数b) 高地址
0x0012FF78 1(参数a) 低地址(栈顶当前)
步骤2:保存返回地址(call指令)

执行call add时,CPU会先把main函数下一条指令的地址(返回地址,假设为0x00401020)压入栈,再跳转到add函数:

  • esp = 0x0012FF78 - 4 = 0x0012FF74
  • 内存地址0x0012FF74存储返回地址0x00401020
步骤3:建立add函数的栈帧

进入add函数后,首先执行栈帧初始化指令:

  1. 保存旧ebp(main的ebp):
    • 执行push ebpesp = 0x0012FF74 - 4 = 0x0012FF70
    • 内存地址0x0012FF70存储0x0012FF80(main的ebp值)。
  2. 设置新ebp(add的栈帧底部):
    • 执行mov ebp, esp,此时ebp = 0x0012FF70(add栈帧的底部,高地址)。
  3. 分配局部变量(比如add的局部变量c):
    • 执行sub esp, 4(分配4字节),esp = 0x0012FF70 - 4 = 0x0012FF6C(add栈帧的顶部,低地址)。
    • 内存地址0x0012FF6C存储局部变量c(初始值随机,比如0)。
最终add栈帧的完整地址分布(高→低)
地址(十六进制) 存储内容 角色 地址属性
0x0012FF70 0x0012FF80(main的ebp) add栈帧底部(ebp) 高地址
0x0012FF74 0x00401020(返回地址) 返回地址 -
0x0012FF78 1(参数a) 函数参数 -
0x0012FF7C 2(参数b) 函数参数 -
0x0012FF6C 0(局部变量c) add栈帧顶部(esp) 低地址

三、补充说明

  1. 上述地址是示例值 ,实际系统中地址会因操作系统(Windows/Linux)、编译器(MSVC/GCC)、ASLR(地址随机化)等因素变化,但高低地址的相对关系永远不变
  2. 64位系统的栈操作逻辑与32位一致,仅地址宽度变为64位(比如0x000000000012FF80),每次push/pop的步长为8字节。
  3. ebp(栈帧基址)的核心作用是"锚定"栈帧:通过ebp+偏移量可以精准访问参数(如ebp+8是参数a)、局部变量(如ebp-4是局部变量c),这是逆向中定位参数/变量的关键。

总结

  1. 内存地址数值越大,地址越高;数值越小,地址越低,栈在x86架构下从高地址向低地址生长。
  2. 栈帧中ebp指向栈帧底部(高地址),esp指向栈帧顶部(低地址),push操作使esp减小,pop使esp增大。
  3. 函数调用时,栈地址从高到低依次存储:旧ebp → 返回地址 → 函数参数 → 局部变量。
相关推荐
ThornArmor41 分钟前
重铸1996|肉体渲染:关节的裂缝:分段模型积木拼装与未成熟的 RSP 矩阵骨骼动画形变
c语言·汇编·c++·python·硬件架构·游戏机
星栖与芯4 小时前
LiteOS-M 切换汇编逐行图解(1):汇编是什么·寄存器与栈
汇编·stm32·嵌入式硬件·harmonyos·鸿蒙系统
yume_sibai7 小时前
11-Rust 不安全编程(unsafe 关键字 + 裸指针 + FFI + 内联汇编 + 内存安全保证)
汇编·安全·rust
小杨不想秃头2 天前
信息安全工程师 历年真题原题汇编(2016–2025)
汇编
2601_9622965111 天前
C/C++:编译全过程——预处理、编译、汇编、链接(包含预处理指令:宏定义,文件包括、条件编译)
汇编·预处理·链接·c/c++·编译过程
Freak嵌入式12 天前
Pico PIO 汇编语法深度详解:标识符、指令、伪指令全解析
汇编·stm32·单片机·嵌入式硬件·fpga开发·硬件架构
kyle~17 天前
x86 汇编LOCK前缀 --- 硬件架构向软件提供的核心同步原语
汇编·c++·性能优化·硬件架构·实时系统
典典分享指南18 天前
飞书 + 企业微信 + 微信文档多端协同实践指南
汇编·flask·intellij-idea·fastapi
极客互动API23 天前
企业微信 iPad 协议服务搭建与 AI 回调实战
网络·汇编·人工智能·微信·企业微信·ipad
wechatbot8881 个月前
极客互动企业微信 SCRM 私域运营实战效果全景
大数据·汇编·微信·自动化·企业微信·rpa