1 / 20

Procedures: Code Generation

Procedures: Code Generation. COP 3402 Software Systems Spring 2014. Procedures: PM/0 code look. In general, when a procedure is compiled, the machine code looks like this:. 00 jmp 0 6 01 jmp 0 2 02 inc 0 5 03 lit 0 2 04 sto 0 5 05 opr 0 0 06 inc 0 4 07 cal 0 2

marvel
Download Presentation

Procedures: Code Generation

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Procedures: Code Generation COP 3402 Software Systems Spring 2014

  2. Procedures: PM/0 code look • In general, when a procedure is compiled, the machine code looks like this: 00 jmp0 6 01 jmp0 2 02 inc 0 5 03 lit 0 2 04 sto 0 5 05 opr 0 0 06 inc 0 4 07 cal 0 2 08 opr 0 0 procedure A; var y; begin y:= 2; end; call A. This code corresponds to the “program” block.

  3. Procedures: PM/0 code look 00 jmp0 6 01 jmp0 2 02 inc 0 5 03 lit 0 2 04 sto 0 5 05 opr 0 0 06 inc 0 4 07 cal 0 2 08 opr 0 0 First comes a ‘jump’ to the actual procedure code. Then we reserve space for the AR and variables. Later comes the code for the procedure. Finally, we return from the call.

  4. Procedures: PM/0 code look • How do I know the address for the first jump? 00 jmp0 6 01 jmp0 2 02 inc 0 5 03 lit 0 2 04 sto 0 5 05 opr 0 0 06 inc 0 4 07 cal 0 2 08 opr 0 0 First comes a ‘jump’ to the actual procedure code. Then we reserve space for the AR and variables. Later comes the code for the procedure. Finally, we return from the call.

  5. Step 1: The “jump” operation jmpCodeAddr = 00 • When we have nested procedures, we don’t know where to jump at the time we have to generate the jump operation. • We must remember where the jump is in order to replace the correct address later. 00 jmp0 ??

  6. Step 1: The “jump” operation jmpCodeAddr = 00 • When we have nested procedures, we don’t know where to jump at the time we have to generate the jump operation. • We must remember where the jump is in order to replace the correct address later. 00 jmp0 ?? 01 jmp 0 2 02 inc 0 5 03 lit 0 2 04 sto 0 5 05 opr 0 0

  7. Step 1: The “jump” operation jmpCodeAddr = 00 • When we have nested procedures, we don’t know where to jump at the time we have to generate the jump operation. • We must remember where the jump is in order to replace the correct address later. 00 jmp0 ?? 01 jmp 0 2 02 inc 0 5 03 lit 0 2 04 sto 0 5 05 opr 0 0 • 06 inc 0 4 …

  8. Step 1: The “jump” operation jmpCodeAddr = 00 • When we have nested procedures, we don’t know where to jump at the time we have to generate the jump operation. • We must remember where the jump is in order to replace the correct address later. 00 jmp0 6 01 jmp 0 2 02 inc 0 5 03 lit 0 2 04 sto 0 5 05 opr 0 0 • 06 inc 0 4 …

  9. Step 1: The “jump” operation • When we parse the procedure declaration, we inserted it’s name into the Symbol Table, but we didn’t know it’s address. • procedure MyProc; • Once we know the address where the procedure code starts, we must: • Update the jump operation. • Update the procedure address in the symbol table.

  10. Step 2: Reserve space • A procedure must reserve space for it’s activation record and variables, before its actual code starts. • We must keep track of how much space we should reserve. It should be 4 at least (for the AR), and must increase for each declared variable. • Be careful: each procedure must keep track of their own space, don’t use a global variable. • To reserve space, we generate a “inc” operation. • gen(INC, 0, SPACE);

  11. Step 3: Procedure code generation • Now we can generate code for the procedure. • This will be handle by the “statement” function.

  12. Step 4: The return call • This one is simple: just generate a return operation (opr 0 0).

  13. Code Generation for Procedure • Step 1: Generate a jump operation. • Store the address of this jump. • Keep parsing/generating code. • Update the jump address. • Update the procedure address in the Symbol Table. • Step 2: Reserve Space • Step 3: Generate the procedure code (parse the statements). • Step 4: Generate a return operation.

  14. Who will handle all this? • The code generation for a procedure is handle by the block function. • <proc-decl> ::= procedure <ident> ; <block> ; | e • <program> ::= <block> . • <block> ::= <const-decl> <var-decl> <proc-decl> <statement>

  15. <block> Parser Procedure <block> ::= <const-decl> <var-decl> <proc-decl> <statement> procedure BLOCK(level); begin if TOKEN = “const” then CONST-DECL(level); if TOKEN = “var” then VAR-DECL(level); if TOKEN = “procedure” then PROC-DECL(level); STATEMENT(level); end;

  16. <block> Parser and Code Generation procedure BLOCK(level); begin space = 4; jmpaddr = gen(JMP, 0, 0); // Step 1 if TOKEN = “const” then CONST-DECL(level); if TOKEN = “var” then VAR-DECL(level, &space); if TOKEN = “procedure” then PROC-DECL(level); code[jmpaddr].addr = NEXT_CODE_ADDR; gen(INC, 0, space); // Step 2 STATEMENT(level); // Step 3 gen(OPR, 0, 0); // Step 4 end;

  17. Keep track of lexicographical level • We need to set the correct lexicographical each time we generate a LOD or STO operation. • We pass the level to each function during parsing recursively, so each function knows at witch level it is working. • Only when PROC-DECL calls BLOCK the level is increased.

  18. Keep track of lexicographical level • To generate a LOD or STO, the correct lexicographical level is given by: current_level – var_level • For example: procedure A; var y; procedure B; var x; begin x = y; end; begin y:= 2; end; call A. y_level = 1 LOD curr_level-y_levely_addr STO curr_level-x_levelx_addr LOD 2-1 5 STO 2-2 5 LOD 1 5 STO 0 5 x_level = 2 curr_level = 2

  19. call Code Generation • At this point, we already know the procedure address, so the call code is easy to generate. procedure STATEMENT; begin … else if TOKEN = "call" then begin GET_TOKEN(); if TOKEN <> IDENT then ERROR (missing identifier); GET_TOKEN(); end …

  20. call Code Generation • At this point, we already know the procedure address, so the call code is easy to generate. procedure STATEMENT; begin … else if TOKEN = "call" then begin GET_TOKEN(); if TOKEN <> IDENT then ERROR (missing identifier); i = find(TOKEN); • if i == 0 then ERROR (Undeclared identifier); if symboltype(i) == PROCEDURE then gen(CAL, 0, symboladdr(i)); • else ERROR(call must be followed by a procedure identifier); GET_TOKEN(); end …

More Related