正在加载图片...
China-pub.coM 379 下载 附录A编译器设计方案 code,c中的实用过程emitRAbsi可以用于这个目的(它接受绝对代码地址,并通过使用当前的 代码产生地址使其相对化)。 例如,假设要调用一个函数,其代码起始地址是27,当前的地址是42。那么代替产生绝对 转移 42:LDC pe,27(* 我们将产生 42:LDA pe,-16(pe) 这是因为27-(42+1)=-16。 1)调用序列调用者和被调用者之间的合理划分是:使调用者除了在rtFO地址存储返回 指针外,还在新的结构中存储参数的值并创建新的结构。代替存储返回指针本身,调用者把它 留在c寄存器中,被调用者把它存储进新的结构。因此,每个函数体必须从在(现在当前的)结 构中存储值的代码开始: ST ac,retro(fp) 这在每个调用点保存一条指令。在返回时,每个函数通过执行指令 LD pe,retFo(fp) 用这个返回地址装入P心。相应地,调用者逐个计算参数,在新结构压栈之前把它们压进栈中相 应的位置。调用者也必须先把当前的p保存进结构的opFO处。从被调用者返回后,通过把旧 的中装入印,调用者丢弃新结构。因此,对有两个参数的函数的调用将产生下列代码: to compute first arg> c offset+1n1tE0(fp】 co +1n1 (Ep) store current fp t (2p to fuction entry LD Ep,ofpFo(fp).pop current frame 2)地址计算因为变量和下标数组都允许出现在赋值表达式的左边,所以在编译期间必须 区分地址和值。例如,在语句 a【1】:=a【+1】 中,表达式a【i]指的是a【i】的地址,而表达式a【i+1]指的是a在地址i+1处的值。这个区分 可以对cGen过程使用一个isAddress参数来实现。当这个参数为真时,cGen产生的代码计 算变量的地址,而不是值。对于简单变量的情况,这意味着加上即(全局变量)或(局部变量) 的偏移量并把结果装入到ac: LDA ac,offset (fp)++put address of local var in ac 对于数组变量的情况,这意味着加上相对于数组基地址的索引值,并把结果装入到,如 下所述。 3)数组在栈中数组的分配从当前结构偏移量开始,按下标增长的顺序在存储器中向下延 伸,如下所示:c o d e . c中的实用过程e m i t R A b s可以用于这个目的(它接受绝对代码地址,并通过使用当前的 代码产生地址使其相对化)。 例如,假设要调用一个函数,其代码起始地址是 2 7,当前的地址是4 2。那么代替产生绝对 转移 42: LDC pc, 27(*) 我们将产生 42: LDA pc, -16(pc) 这是因为27 - (42 + 1) = -1 6。 1) 调用序列 调用者和被调用者之间的合理划分是:使调用者除了在 r e t F O地址存储返回 指针外,还在新的结构中存储参数的值并创建新的结构。代替存储返回指针本身,调用者把它 留在a c寄存器中,被调用者把它存储进新的结构。因此,每个函数体必须从在 (现在当前的)结 构中存储值的代码开始: ST ac, retFO(fp) 这在每个调用点保存一条指令。在返回时,每个函数通过执行指令 LD pc, retFO(fp) 用这个返回地址装入p c。相应地,调用者逐个计算参数,在新结构压栈之前把它们压进栈中相 应的位置。调用者也必须先把当前的 f p保存进结构的o f p F O处。从被调用者返回后,通过把旧 的f p装入f p,调用者丢弃新结构。因此,对有两个参数的函数的调用将产生下列代码: <code to compute first arg> ST ac, frameoffset+initFO (fp) <code to compute second arg> ST ac, frameoffset+initFO-1 (fp) ST fp, frameoffset+ofpFO (fp) * store current fp LDA fp, frameoffset(fp) * push new frame LDA ac,1(pc) * save return in ac LDA pc, ...(pc) * relative jump to fuction entry LD fp, ofpFO(fp) * pop current frame 2) 地址计算 因为变量和下标数组都允许出现在赋值表达式的左边,所以在编译期间必须 区分地址和值。例如,在语句 a[i] := a[i+1]; 中,表达式a [ i ]指的是a [ i ]的地址,而表达式a [ i + 1 ]指的是a在地址i + 1处的值。这个区分 可以对c G e n过程使用一个i s A d d r e s s参数来实现。当这个参数为真时, c G e n产生的代码计 算变量的地址,而不是值。对于简单变量的情况,这意味着加上 g p (全局变量)或f p (局部变量) 的偏移量并把结果装入到a c: LDA ac, offset(fp) ** put address of local var in ac 对于数组变量的情况,这意味着加上相对于数组基地址的索引值,并把结果装入到 a c,如 下所述。 3) 数组 在栈中数组的分配从当前结构偏移量开始,按下标增长的顺序在存储器中向下延 伸,如下所示: 附录A 编译器设计方案 3 7 9 下载
<<向上翻页向下翻页>>
©2008-现在 cucdc.com 高等教育资讯网 版权所有