210 likes | 502 Views
Stack Machine ISA. Arithmetic/Logic Instruction: Unary operation: pop top element of stack, apply operation, push result onto stack. NEGATE. 1. -1. …. …. NOT. 1. 0. …. …. Arithmetic/Logic Instruction: Binary operation: pop two top element of stack,
E N D
Stack Machine ISA • Arithmetic/Logic Instruction: • Unary operation: • pop top element of stack, • apply operation, • push result onto stack. NEGATE 1 -1 … … NOT 1 0 … …
Arithmetic/Logic Instruction: • Binary operation: • pop two top element of stack, • apply operation as top element on left hand, second element of right hand. • push result onto stack. 3 SUB 2 -1 … …
Control • unconditional jump • jump [label][+/-offset] : • jump to the label. • conditional jump • branch_true [label][+/-offset] • branch_false [label][+/-offset] • exit : terminate program.
Stack manipulate • push • push_const <constant> • push_reg <reg> • pop • pop_reg <reg> • shift_sp <integer constant>
assign/fetch • assign : assign value of the top element into address specified by second element, and pop two top elements. 3 assign glob … … glob: ? glob: 3
assign/fetch • fetch : get value from the address the top element specifies, and pop the top element and push the value into stack. fetch glob 3 … … glob: 3
assign/fetch push_reg sp fetch this sequence copy value of stack top sp 3 push sp fetch 3 3 3 … … …
I/O • read_int • Read an integer using scanf(“%d”) • write_int • write_string • Global Data <label>. data <size> <label>. string <string>
start up code. push_const EXIT push_reg fp push_reg sp pop_reg fp jump main EXIT: exit • allocate global data area • Lglob. data <uninitialized global data size>
What is Difficult? int *x; int *y; y = &*x; /* y=x */ y = &(*x++); /* y=x, x=x+sizeof(int) */ y = x++; /* y=x, x=x+sizeof(int) */ y = ++x; /* y=x+sizeof(int), x=x+sizeof(int) */ y = x++ +x; /* y=2x+sizeof(int), x=x+sizeof(int) */ y = ++x + x; /* y=2(x+sizeof(int)), x=x+sizeof(int) */ *y = *x++; /* *y=*x, x = x+sizeof(int) */
y = &*x; /* y=x */ push &y /* y */ /* fetch */ push &x /* unary->ID(x) */ fetch /* fetch */ /* unary->*ID(x) */ assign I think buffering is a good idea...
y = *x; /* y=*x */ push &y /* y */ /* fetch */ push &x /* unary->ID(x) */ fetch fetch /* unary->*ID(x) */ assign I think buffering is a good idea...
y = x++; /* y=x, x=x+sizeof(int) */ push &y push &x push sp fetch /*copy &x*/ push sp fetch /*copy &x*/ fetch /*get x*/
y = x++; /* y=x, x=x+sizeof(int) */ push_const sizeof(*x) add assign /* x=x+sizeof(*x)*/ fetch /*get x*/ push_const sizeof(*x) sub /*x=x-sizeof(*x)*/ assign /*y=x*/
if(f1() && f2()) { stmt1 } /* if f1 return true, call f2 and if f2 return true, * then execute stmt1 * if f1 return false, do not call f2. */ if(f1() || f2()) { stmt2 } /* if f1 return false, call f2 and if f2 return true, * then execute stmt1 * if f1 return true, do not call f2 and execute stmt2 */
for(exp1; cond; exp2) { /* cond may be consist of */ if(a) break; /* binary operation using */ if(b) continue; /* &&, || */ stmt1; }; while(cond) { if(a) break; if(b) continue; stmt2; };
for(exp1; cond1 && cond2; exp2) if(a) break; if(b) continue; stmt1; }; We must determine where to branch if cond1 is false, just after reduced cond1 and &&.
IF structure. check condition. T-Label: /* condition is true. */ execute stmt. F-Label: /* condition is false. */ LOOP structure. C-label: /* continue comes here */ check condition. T-label: /* condition is true. */ execute stmt. jump C-label. B-label: /* break comes here, condition is false. */
Labels should be “stacked”. There are many kind of labels. S.T. Continue-label, True-label, False-label, Return-Address-label...