1) Accumulator: Load b mul c store a add c store b sub d store temp load b div temp store c temp: number Each command takes 1 byte for the opcode and 2 bytes for the address, and 4 bytes data. 30 code bytes, 40 data bytes. total 70 bytes. Memory-to-Memory: For this, I made all instructions dest, source, source mul a,b,c add b,a,c sub temp,b,d div c,b,temp temp: number Each command takes 7 bytes code, 12 bytes data. 28 code bytes, 48 data bytes. total 76 bytes. Stack: push b push c mul pop a push a push c add pop b push b push d sub push b div pop c Pushes and pops take 3 bytes code, 4 bytes data. Arithmetic operations take 1 byte code, 0 bytes data. 44 code bytes, 40 data bytes. total 84 bytes. You could have used DUP instructions to cut this down somewhat. Load/Store: For this, I made all arithmetic instructions dest, source, source load R2,b load R3,c mul R1,R2,R3 ; a = b * c store R1,a add R2,R1,R3 ; b = a * c store R2,b load R4,d sub R5,R2,R4 ; temp = b-d div R3,R2,R5 ; b = b/temp store R3,c Loads and stores take 4 bytes code, 4 bytes data. arithmetic operations take 3 bytes code. 36 code bytes, 24 data bytes. total 60 bytes. Overall, load store should be most efficient - some of you found that the stack machine was more efficient by abusing the order of operands to SUB and DIV, or by using the DUP instruction. Memory-to-memory is most efficient in code-size. ---------------------------------------------------- 2a) In C, this is the line "R4 = (R3 >> 7) & 0xF;" In assembly, this is: move R4,R3 shr R4,7 and R4,0xF 2b) In C, this is the code: R1 = (R5 & 0xf) << 7; R3 &= 0xFFFFF87F; R3 |= R1; In assembly, this is: move R1,R5 and R1,0xf shl R1,7 and R3,0xfffff87f or R3,R1 All the above instructions have operands in the order destination,source. Note that bits are counted starting from 0, not 1. Also, they are counted left to right. So the bits in a byte look like: 172(decimal) = 10101100(binary) -------- 76543210 Also note that in 2b, we ANDed R3 before ORing the new bits in. This is to make sure those bits are clear. Otherwise, if any of those bits are 1, they could override a potential zero we are ORing in. ------------------------------------ 3a) int gcd(int m,int n) { int myTemp; if (m==n) return m; if (m>n) { myTemp=m-n; } if (n>m) { myTemp=n-m; } return myTemp; } Almost anything reasonable is acceptable as long as it's written in a language like C or Java, uses at least one temp variable, and computes GCD. 3b) See the accompanying .jpg file. Note that the Stack Pointer (SP) always points to the top of the stack. The Frame Pointer (FP) always points to the most recent Old Frame Pointer (oldFP) stored in the stack. You should also indicate where the old frame pointers are pointing to. The bottom-most oldFP (the one corresponding to the 'main' function) points back to the function in the operating system that invoked 'main'. It's okay if you had local variables allocated on the stack while calling the 'gcd' function. The important parts are that the local variable was in the stack for previous calls, and also on the top of the stack after 'gcd' started returning.