请教:活动记录
最近看虎书,对“活动记录”一章有以下疑问:
1、在 Frame.h, Frame.c 中,要实现 F_newFrame(), F_allocLocal() , InFrame(), InReg() 这几个函数功能的话,首先要确定 frame 的结构。按照书上对 frame 的描述为:{局部变量列表,返回地址,临时变量列表,实参列表,静态链,函数名字(frame名字),*fp,*sp}。但是书上只是提到在 F_newframe 的时候只需要2个参数(即 Temp_label name 和 F_accessList formals)。本人倾向于将frame的结构定为:{局部变量列表,返回地址,临时变量列表,实参列表,静态链,函数名字(frame名字),*fp,*sp}。不知道各位有何看法?
2、接着上面的问题,对于frame的结构定为:{局部变量列表,返回地址,临时变量列表,实参列表,静态链,函数名字(frame名字),*fp,*sp},我们需要为frame的元素分配内存空间(假设都是逃逸的)吗?这个问题似乎没必要问,活动记录里面存放的就是函数里各种数据的信息,不分配空间怎么行!但是,前一章里面,我已建立了符号表,并且已将相关符号的名字和类型信息存入符号表,而且符号表是已分配内存空间了的。那是不是说frame管的就是“变量的值”,而符号表管的是“变量/函数的类型,作用域”等这些信息呢?如果是的话,frame和符号表之间如何交叉?是通过变量名字/函数名字吗?如果是的话,在使用 Temp_newlabel() (在 temp.c )为变量和函数另外取名的,该如何对应?(Temp_newlabel()并不是像散列函数一样通过算法得出新的名字的)。
3、有关 *fp , *sp。 按书上描述, 当函数 g() 调用 函数 f(), 栈指针首先指向 f() 的第一个参数(这时处于函数 g()的frame中),然后进入函数f(),"当前 fp" = sp , "当前 sp" = fp - 函数f() 的 frame长度。我的理解是:在未进入函数体之前(即“当函数 g() 调用 函数 f(), 栈指针首先指向 f() 的第一个参数(这时处于函数 g()的frame中)),在 函数声明 匹配后(即 semant.c 中的transDec中 case A_functiondec 匹配),就可以进行 F_newframe , 而每个函数体里用到的变量会在 transDec 中 case A_vardec 匹配,即匹配变量声明后再记录入frame。如果以上我的理解没错的话,那么 当调用 F_newframe 时 frame 的长度是未最终确定的。如果要等到frame长度确定的话,恐怕要在函数的出口处。也就是说,问题的焦点在:F_newframe时未能确定 *fp 和 *sp,也未能提供从 *fp开始的一片大小为(fp - sp)的空间,这使得frame中的成员没有数据存放的地方(空指针)!因此,我想请教:在什么时候设置 *fp, *sp ? 如何设置。
4、有关返回地址。对于汇编,我知道返回地址放在 CS:IP 中,但如何用C 去将 “汇编指令 CALL”的下一个动作 PUSH CS,PUSH IP 转成 C语言并将CS和IP放进frame中的返回地址处。当函数返回时又该如何做?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
先顶一下
void foo(char *s)
{
printf("I'm foo()...%s\n", s);
}
int main()
{
char *s = "hello";
foo(s);
}
-----------------------------------------
相应的汇编码大致如下:
foo:
push ebp
mov ebp, esp
push dword ptr [ebp+8]
push $LC0
call printf
pop ebp
ret
main:
push ebp
mov ebp, esp
sub esp,4
push dword ptr [ebp-4]
call foo
add esp,0x0c
pop ebp
ret
---------------------------------------------
用 c 来实现 call 指令的行为:
void _call((void(*)())fn)
{
*++reg.esp = reg.cs;
*++reg.esp = reg.eip;
fn();
}
void do_main()
{
*++reg.esp = reg.ebp;
reg.ebp = reg.esp;
reg.esp -- ;
*(reg.ebp-1) = s;
_call(foo);
}
谢楼上。
实在看的太烦了,虎书里也太精简了。各位谁有 semant.c translate.c frame.c(到中间代码生成这章)的 source ? 有的话共享一下,谢谢。
源代码。
别瞎翻译了,frame就是frame。
虎书是教科书,得老师给你讲,当然你智商高的话就可以自学了,比如我这样的智商,60
yhb04,谢谢。
yhb04,
最近在调试,发现 let declist in exp 有些问题,识别不了多个表达式(declist),在改动tiger.grm之后,原来的错误没了,但是却出现了其他的错误。回头看你的文件包里,却没有发现你的tiger.grm,能把你的那个 tiger.grm 一并共享给我吗?谢谢。
tiger.grm是什么东东?难道是描述Tiger的语法的yacc文件?
文件包里的源代码应该是全的,描述语法的yacc文件是 myparser.y 。
yhb04,
看到了,对,就是myarser.y这个文件