✏️

语义分析

Created
Oct 9, 2024 02:51 AM
符号表管理
  • 主要是记录目前的编译阶段代码啥情况
  • 分程序(Procedure内部还有Procedure)
    • 栈式线性符号表
      • 符号表还是线性(即从程序开始扫到最后,依次记录符号信息)的,但是再拿一个栈来记录当前Block的层数
      • Procedure不用记录
    • 哈希
  • 非分程序(例如C)
    • 类似,此时把定义的函数当成变量看
 
 
静态存储分配
  • 编译的时候就给变量分配好内存
  • 不好用,不一定在编译时就能确定变量所占空间
 
运行时存储分配
FORTRAN:
  • 编译程序生成有关存储分配的目标代码
  • 活动记录
    • 每个Block在运行时有一个,共同构成程序的执行栈
    • 局部数据区
      • 注意定义的函数不出现在这,只出现在符号表里
    • 参数区
      • notion image
      • prev abp: 调用该模块的模块记录的基地址,函数执行完后,当前指针指向caller的活动记录基地址
      • ret addr: caller的调用语句的下一条指令的地址(代码段)
      • ret value: 返回值
    • display区
      • 所有外层模块的基地址
      • 所有外层变量的二元地址(BL, ON)
        • BL: 变量所属的层次
        • ON: 相对于该层的显式参数区开始位置的offset
      • i层调用j层时
        • j = i + 1 (内部定义)
          • j的display会复制i的display,然后再加一条i的abp
        • j ≤ i (调用外层或同层模块)
          • 复制前j - 1层abp
  • 运行时地址计算
    • 访问变量的地址
notion image
  • 迭代情况
    • 当成同层调用就行
 
C语言:
notion image
进行函数调用时加个栈帧
ebp: sf的栈底指针
esp: sf栈顶
eip: 函数调用栈(?)指向当前函数名
 
 
不同架构对函数参数的存储有不同的约束
e.g. R1-R4用于记录前四个参数,之后的参数再开一片区域单独传
c/c++使用cdecl调用规定,函数参数从右往左依次传入
 
垃圾回收