程序和指令的代价 下面假设指令的代价为1加上对运算分量寻址的 代价 寄存器寻址的附加代价为0 ·涉及内存位置的寻址方式的附加代价为1 例如: LDRO,R1代价为1 LDRO,M代价为2 LDR1*100(R2)代价为2 ·代码生成算法的目标是使程序在典型输入上运行 时的指令代价总和最小
程序和指令的代价 • 下面假设指令的代价为1加上对运算分量寻址的 代价 • 寄存器寻址的附加代价为0 • 涉及内存位置的寻址方式的附加代价为1 • 例如: • LD R0, R1 代价为1 • LD R0, M 代价为2 • LD R1,*100(R2) 代价为2 • 代码生成算法的目标是使程序在典型输入上运行 时的指令代价总和最小
代码生成怎么做? 过程调用和返回的代码生成,名字(过程名或变 量名)的运行时刻地址 ·将中间代码划分为基本块,形成流图 ·为单个基本块生成代码的简单的算法 ·窥孔优化:对目标代码进行优化 全局寄存器分配算法:图着色方法 基于树重写的指令选择
代码生成怎么做? • 过程调用和返回的代码生成,名字(过程名或变 量名)的运行时刻地址 • 将中间代码划分为基本块,形成流图 • 为单个基本块生成代码的简单的算法 • 窥孔优化:对目标代码进行优化 • 全局寄存器分配算法:图着色方法 • 基于树重写的指令选择
回顾程序运行时空间的划分 代码区 靠近栈底 实在参数 静态区 返回值 控制链 堆区 访问链 空闲内存 保存的机器状态 局部数据 栈区 临时变量 靠近栈顶 图7-1运行时刻内存被划分成代码 区和数据区的典型方式
回顾程序运行时空间的划分 靠近栈底 靠近栈顶
活动记录的栈分配 寄存器SP指向栈顶的活动记录的开始处 ·第一个过程main初始化栈区 LD SP #stack start //初始化栈 code for the first procedure HALT //结束执行 HA[T指令把控制返回给操作系统
活动记录的栈分配 • 寄存器SP指向栈顶的活动记录的开始处 • 第一个过程main初始化栈区 • HALT指令把控制返回给操作系统
活动记录的栈分配 过程调用时, caller增加sP的值,保存返回地址, 并把控制传递给cale ADD SPSP# caller record size∥/增加栈指针 ST0(SP),#here+16∥/保存返回地址(BR后的指令地址) bR callee codearea∥/跳转到cale的第一条指令的地址 返回时,caee把控制传递给返回地址, caller把SP 恢复为以前的值 callee中:BR*o(SP) caller +: SUB SP, SP, #caller. recordSize
活动记录的栈分配 • 过程调用时,caller增加SP的值,保存返回地址, 并把控制传递给callee • ADD SP, SP, #caller.recordSize // 增加栈指针 • ST 0(SP), #here+16 // 保存返回地址(BR后的指令地址) • BR callee.codeArea // 跳转到callee的第一条指令的地址 • 返回时,callee把控制传递给返回地址,caller把SP 恢复为以前的值 • callee中:BR *0(SP) • caller中:SUB SP, SP, #caller.recordSize