tips
栈 栈指针 帧 帧指针 Frame 模块: 栈帧相关信息 F_frame : 栈帧
F_access : 表示 寄存器 / 栈帧 的地址偏移, 即位置 Symbol Temp_label : 标识符 F_newFrame(label, boolList) : 生成 符号 label 对应的新栈帧 F_formals() : 返回形参的 access F_allocLocal() : 返回局部变量的 access Translate 模块: 关联 栈帧 和 语义分析 , 相比 F_access, 添加了 level 信息 Tr_access : 函数层 (标识嵌套信息) 与 栈帧信息 F_frame { Tr_level, F_access} Tr_level : 嵌套层, 函数嵌套关系 Tr_allocLocal() : 带 level 信息的局部变量 Tr_access Tr_formals() : 带 level 信息的形参 Tr_access Tr_newLevel() : 创建新的函数层
Tr_newLevel(
level_包围层, ( 函数 f 的包围层, 即调用者 )
f_当前层函数,
[ 标记形参是否逃逸的 Bool 数组 (第一个元素对应静态链)]
)
Tr_outermost() : 最外层函数标识
transDec()
transExp()
transVar()
LIFO: 递归函数调用 -> 栈 存储
高阶函数: 支持递归调用, 支持以函数做为返回值, 不能用简单的 栈来存储,(在15章讨论)
栈 + 栈指针:
指针右侧: 垃圾回收
指针左侧: local 变量
活动记录: activity record , 栈帧: stack frame
标准结构 : 可以实现 跨语言调用
栈地址 : 从高到低
栈帧 Stack Frames
帧指针 Frame Pointer & 栈指针 Stack Pointer
Stack Frame: 栈帧 SP: Stack Pointer 栈指针 FP: Frame Pointer 帧指针
f( ... ) {
...
g(x,y,....)
...
}
执行 函数 f()时,栈指针SP 在位置A, 执行到 g(x,y,... )时发现要调用函数 g, 则SP -= FRAME_SIZE, 新的FP指向 SP 的地址。 新 FP ~ 新SP 的 FRAME_SIZE 个地址则保存调用过程中的所有数据, 以备后来之用。 参数传递
前 k 个放在寄存器中 (一般中 k=4 或 k=6) f(g()): 临时变量 x 在函数 f() 调用以后不再需要: 放入一个调用者保护的寄存器中, 调用 g() 时不保护它 局部变量 i (f()内部)在函数 g( ) 调用前后都需要: f() 入口 放入被 调用保护 寄存器 ri 一次 , f()出口取回一次 返回地址
call 指令地址 + 1 => 放入 寄存器 => 非叶过程 后面还有指令要跑, 所有结束后 还要等, 需要把地址存在自己的栈帧里面 寄存器 or 栈帧 ?
寄存器中: 参数:寄存器中 返回地址:寄存器中 函数结果:寄存器中 返回 局部变量,中间结果:寄存器中 栈帧(存储)中: 1. 传址变量:变量为一地址 ( &p ) 2. 该变量被嵌套在当前过程(函数)内的过程(其他函数)访问 3. 变量值太大,不能放在单个寄存器中 ( 32位,4字节 或 64位, 8字节 ) 4. 变量是一个数组,元素需要地址运算(C语言) 5. 需要使用存放该变量的寄存器 6. 太多局部变量 临时变量, 无法全部放入寄存器中 7. 函数参数大于k个 (k一般为 4 到 5个) 标签:函数,记录,Tr,access,寄存器,活动,栈帧,指针 From: https://www.cnblogs.com/wuoshiwzm/p/18076094