目标代码中的地址 如何为过程调用和返回生成代码? 静态分配(活动记录) 栈式分配(活动记录) 如何将R中的名字(过程名或变量名)转换成为目 标代码中的地址? 不同区域中的名字采用不同的寻址方式 11
目标代码中的地址 • 如何为过程调用和返回生成代码? – 静态分配 (活动记录) – 栈式分配 (活动记录) • 如何将IR中的名字 (过程名或变量名) 转换成为目 标代码中的地址? – 不同区域中的名字采用不同的寻址方式 11 南大编译许畅
活动记录的静态分配 每个过程静态地分配一个数据区域,其开始位置 用staticArea表示 。call callee的实现 ST callee.staticArea,#here+20/∥存放返▣地址 BR callee.codeArea callee中的语句return BR *callee.staticArea 12
活动记录的静态分配 • 每个过程静态地分配一个数据区域,其开始位置 用staticArea表示 • call callee的实现 – ST callee.staticArea, #here + 20 // 存放返回地址 – BR callee.codeArea • callee中的语句return – BR *callee.staticArea 12 南大编译许畅
例子 ·三地址代码 //c的代码 100: ACTION //action1的代码 c的代码 120: ST364, #140 //在位置364上存放返回地址140 132: BR200 /调用p action 140: ACTION2 call p 160: HALT //返回操作系统 action2 //p的代码 halt 200: ACTION3 220: p的代码 BR*364 //返回在位置364保存的地址处 action3 //300-363存放c的活动记录 300: return //返回地址 304: /c的局部数据 //364451存放p的活动记录 364: //返回地址 368: /p的局部数据 13
例子• 三地址代码 – c的代码 • action1 • call p • action2 • halt – p的代码 • action3 • return 13 南大编译许畅
活动记录的栈式分配 寄存器SP指向栈顶 第一个过程(main)初始化栈区 过程调用指令序列 ADD SP,SP,#caller.recordSize ∥增大栈指针 ST O(SP),#here +16 /川保存返回地址 BR callee.codeArea 川转移到被调用者 。返回指令序列 BR*0(SP) 川被调用者执行,返回调用者 SUB SP,SP,#caller.recordSize/∥调用者减小栈指针 14
活动记录的栈式分配 • 寄存器SP指向栈顶 • 第一个过程 (main) 初始化栈区 • 过程调用指令序列 – ADD SP, SP, #caller.recordSize // 增大栈指针 – ST 0(SP), #here + 16 // 保存返回地址 – BR callee.codeArea // 转移到被调用者 • 返回指令序列 – BR *0(SP) // 被调用者执行,返回调用者 – SUB SP, SP, #caller.recordSize // 调用者减小栈指针 14 南大编译许畅
例子 m的代码 100: LD SP,#600 /1初始化栈 108: ACTION /1 action1的代码 128: ADD SP, SP, #msize /1 调用指令序列的开始 136: ST*SP,#152 /将返回地址压入栈 144: BR300 调用g m调用q,q调用p 152: SUB SP,SP,#msize 恢复SP的值 160: ACTION2 180: HALT p的代码 200: ACTION3 220: BR *0(SP) /1返回 q的代码 372: ADD SP,SP,#gsize 300: ACTION //包含有跳转到456 380: BR*SP,#396 /将返回地址压入栈 320: ADD SP, SP,#gsize 388: BR300 /1调用9 328: ST *SP, #344 /将返回地址压入栈 396: SUB SP,SP,#gsize 336: BR200 /调用P 404: ACTION6 344: SUB SP,SP, #gsize 424: ADD SP,SP,#gsize 352: ACTION5 432: ST*SP,#440 //将返回地址压入栈 440: BR300 //调用9 448: SUB SP,SP,#gsize 图8-6 栈式分配时的目标代码 456: BR *0(SP) //返回 600: /1栈区的开始处 15
例子 15 m调用q,q调用p 南大编译许畅