Control-Flow Graph to Assembly with Global Variables

Recall SimpleCFG.scala from Lecture 11

How to compile e.g. a quadruple?

x = y * z

One possibility: translate each quadruple independently into machine instruction sequence such as

Move(Register(r1), Memory(yAddr))
Move(Register(r2), Memory(zAddr))
Quad(Register(r1), Register(r1), Register(r2))
Move(Memory(xAddr), Register(r1))

How do we pick

  • r1, r2 - pick any general purpose register
  • xAddr, yAddr, zAddr
    • let assember pick them (usually sequentially in 'data segment' part of process image)
    • remark: linker can shift these, and virtual memory hardware can shift them again

Branching instructions etc. are similar, just make sure operands are in the right place


  • simple
  • work for arbitrarily complex expressions
    • translation to CFG introduces additional variables


  • occupies static memory if these are global variables
    • better to allocate them on stack
    • we will explain how stack looks like in machine code
  • can introduce unnecessary memory operations
    • much more expensive than CPU operations
    • much better if we can avoid re-loading value from memory
    • register allocation



res = x * y + y * z + x * z

can be expressed as compilation of this program

static int x;
static int y;
static int z;
static int res;
static int xy;
static int yz;
static int xz; 
static int res1;
int f() {
  xy = x * y;
  yz = y * z;
  xz = x * z;
  res1 = xy + yz;
  res = res1 + xz;

which (using gcc -S) generates assembly code of this form

movl	x, %edx
movl	y, %eax
imull	%edx, %eax
movl	%eax, xy
movl	y, %edx
movl	z, %eax
imull	%edx, %eax
movl	%eax, yz
movl	x, %edx
movl	z, %eax
imull	%edx, %eax
movl	%eax, xz
movl	xy, %edx
movl	yz, %eax
leal	(%edx,%eax), %eax
movl	%eax, res1
movl	res1, %edx
movl	xz, %eax
leal	(%edx,%eax), %eax
movl	%eax, res

The 'leal' instruction above

  • means 'load effective address, long'
  • here used simply as addition of registers
leal (%edx,%eax), %eax


%eax = %edx + %eax