I'm writing a simple toy compiler and I come to the part of generating machine code (x86-32 assembly in this case). This is what I have for now:
Given the assignment statement: d := (a-b)+(c-a)-(d+b)*(c+1)
I first generate the following intermediate code (3 address code in Triples form):
(0) sub, a, b
(1) sub, c, a
(2) add, (0), (1)
(3) add, d, b
(4) add, c, 1
(5) mul, (3), (4)
(6) sub, (2), (5)
(7) asn, d, (6)
I'm using an intermediate code with the hope of later perform some optimizations on it. For now, I don't manipulate the 3AC and directly generate assembly from it.
My scheme for register use is the following: I perform all the arithmetic operations using EAX and save intermediate results in the other registers EBX, ECX and EDX. For example, from the previous 3AC I generate the following assembly:
mov eax, a
sub eax, b ; eax = (0)
mov ebx, eax ; ebx = (0) & eax = free
mov eax, c
sub eax, a ; eax = (1)
add ebx, eax ; ebx = (2) & eax = free
mov eax, d
add eax, b ; eax = (3)
mov ecx, eax ; ecx = (3) & eax = free
mov eax, c
add eax, 1 ; eax = (4)
imul ecx ; eax = (5) & ecx = free
sub ebx, eax ; ebx = (6) & eax = free
mov eax, ebx ; eax = (6) & ebx = free
mov d, eax
My question is: what do I do when I need to spill the result of EAX but all the registers are busy (EBX, ECX and EDX are holding temporaries). Should I save the value of EAX in the stack and recover it later? If that is the case, should I reserve some extra space in the stack frame of every function for that extra temporaries?
I repeat, this is only what I have come to for now. If there is other simple scheme for allocate registers I would like to know (I'm aware of the existence of more complex solutions involving graph coloring, etc; but I'm looking only for something simple that just works).
pushandpopwhich shouldn't break the stack only when necessary. Also, maybe this could help: en.wikipedia.org/wiki/Sethi%E2%80%93Ullman_algorithm. - paulotorrensah/al,bh/bl, etc. - paulotorrens