Translator.translateCallExpr方法中关于设置函数入参偏移量的问题

来源:6-13 (编程 trans 04 java)翻译——作用域和整体程序

老谭客

2020-09-06

原代码如下

private Symbol translateCallExpr(TAProgram program, ASTNode node, SymbolTable symbolTable) throws ParseException {
        //函数名称
        var factor = node.getChild(0);



        var list = new ArrayList<TAInstruction>();
        //函数入参
        for(int i = 1; i < node.getChildren().size(); i++) {
            var expr = node.getChildren().get(i);
            //由于参数可以是表达式,所以通过translateExpr进行翻译
            var addr = translateExpr(program, expr, symbolTable);
            list.add(new TAInstruction(TAInstructionType.PARAM, null, null, addr, i - 1));
        }

        //将arg2设置为offset
        for(var instruction : list) {
            instruction.setArg2( symbolTable.localSize() + (int)instruction.getArg2() + 2);
            program.add(instruction);
        }

        //函数返回值
        var returnValue = symbolTable.createVariable();
        //函数返回地址
        var funcAddr = symbolTable.cloneFromSymbolTree(factor.getLexeme(), 0);
        if(funcAddr == null) {
            throw new ParseException("function " + factor.getLexeme().getValue() + " not found");
        }
        //函数压栈,消耗栈空间symbolTable.localSize()个单位
        program.add(new TAInstruction(TAInstructionType.SP, null, null,
                -symbolTable.localSize(), null));
        program.add(new TAInstruction(TAInstructionType.CALL, null, null, funcAddr, null));
        //函数出栈,恢复栈空间
        program.add(new TAInstruction(TAInstructionType.SP, null, null,
            symbolTable.localSize(),null));
        return returnValue;
    }

为什么在设置入参偏移量的时候会+2,视频中好像没解释?

   //将arg2设置为offset
        for(var instruction : list) {
            instruction.setArg2( symbolTable.localSize() + (int)instruction.getArg2() + 2);
            program.add(instruction);
        }
写回答

1回答

求老仙

2020-09-09

每次函数调用会产生一个活动记录,返回值、返回地址会先于参数被压栈。因此执行到这里有个2,对应返回值和返回地址的偏移量。

0
0

大学计算机必修课新讲--编译原理+操作系统+图形学

轻松超越大学课程,前阿里P8专家的实践精华总结

1752 学习 · 157 问题

查看课程