Miscellaneous Notes and Hints on the Compiler 0. On compiling the "main" class and method. The main class and main method should be treated the same way as other classes and methods, You need to first locate the symbol table entry for the main class: visit(mainclass x) { ... cclass = (classentry)top.lookup(x.classname); Then, use cclass to look up the main method: cmethod = (funcentry)cclass.lookup("main"); The next thing you need to do is to find out how many local variables is in main. This information is the size of the "locals" hashtable inside the cmethod funcentry object: int numlocals = cmethod.locals.size(); Now you know how much to sub from %esp to allocate memory for these variables ... Please try to understand the logic of these hints before simply typing them in. Otherwise, they still won't really help you. 1. On Division. This is a minor point about the compiler, but several people have asked me about it: The idiv operation for signed division works differently from imul, add and sub: it divides a 64 bit value by a 32 bit value. The 64 bit value must be stored in the two registers edx:eax. That is, the two registers EdxEax are used side-by-side to form a 64 bit value. idiv takes only one operand, which must be a register or mem operand. The result of the division after the idiv operation is that: the quotient is left in the eax register and the remainder is left in the edx register. For example, the following code computes 128/8 and prints the answer (16): Notice that even though 128 doesn't need 64 bits, we still have to move 0 into edx: .section .rodata STR0: .string "answer = %d\n" .globl main main: mov $0,%edx # clears edx mov $128,%eax # forms number to be divided in edx:eax mov $8,%ebx # move number to divide by in register idiv %ebx # divides edx:eax by the value in ebx /* at this point, the answer (16) is placed in eax and the remainder (0) in edx */ push %eax # printf the answer in eax push $STR0 call printf add $8,%esp push $0 call exit You cannot just say idiv $8 because the operand must be either a register or memory operand. There is another compilication: if the number you need to divide by is negative, say -128, then you cannot move $0 into edx, because the two's complement representation of -128 will start with 11111.... Therefore, you must move all 1's into edx: mov $0xffffffff, %edx The prefix "0x" preceeds all hexadecimal values. Alternatively, 0xffffffff is just -1 in two's complement, so you can also do: mov $0, %edx sub $1, %edx Since Java only defines division for 32-bit values, you must either mov 0 or 0xffffffff into edx first. So to really compile division correctly, you need to also generate code to first see if the value is negative, something like: mov $0, %edx cmp $0, %eax jge posdiv0: sub $1, %edx posdiv0: idiv ... Anyway, don't worry about division too much unless you have the time. ---------- -- Check back for additional hints ...