Explain what Beta assembly language instruction(s) are needed
to load the value of a variable that has been allocated in the first
32k bytes of main memory (i.e., at an address less than 0x8000).
How would your answer change if the variable was located at address
outside this range (e.g., at address 0x12468).
vaddr: LONG(0x12468) ... LDR(vaddr,R0) ; load address of variable into R0 LD(R0,0,R0) ; load Mem[address] into R0
a = b + 3*c;
LD(c,R1) SHLC(R1,1,R0) ; 2*c ADD(R0,R1,R0) ; + c LD(b,R1) ADD(R1,R0,R0) ST(R0,a)
if (a > b) c = 17;
LD(a,R0) LD(b,R1) CMPLE(R0,R1,R0) BT(R0,_L2) CMOVE(17,R0) ST(R0,c) _L2:
LD(sxt_short,R0) BEQ(R0,_L3) LD(b,R1) SHLC(R1,16,R0) ; shift so that bit 15 is now bit 31 SRAC(R0,16,R0) ; shift back, replicating sign bit ST(R0,b)
LD(cjt,R1) LD(R1,8,R0) ADDC(R0,3752,R0) ST(R0,8,R1)
LD(i,R0) SHLC(R0,2,R0) LD(R0,a-4,R1) ST(R1,a,R0)
sum = 0;ST(R31,sum) ST(R31,i) _L7: LD(sum,R0) LD(i,R1) ADD(R0,R1,R0) ST(R0,sum) ADDC(R1,1,R1) ST(R1,i) CMPLTC(R1,10,R0) BT(R0,_L7)
int sum = 0;
{ int i;
for (i = 0; i < 10; i = i+1) sum += i;
}
MOVE(R31,R2) ; R2 holds sum ST(R2,sum) MOVE(R31,R1) ; R1 holds i _L5: ADD(R2,R1,R2) ADDC(R1,1,R1) CMPLTC(R1,10,R0) BT(R0,_L5) ST(R2,sum)
int sum = 0;
{ int i;
for (i = 0; i < 10; i = i+2) { sum += i; sum += i+1; }
}
Hand-compile this loop into Beta assembly language and compare the
total number of memory accesses generated when it executes to the
total number of memory accesses from part (1).
MOVE(R31,R2) ; R2 holds sum ST(R2,sum) MOVE(R31,R1) ; R1 holds i _L5: ADD(R2,R1,R2) ADDC(R1,1,R0) ADD(R2,R0,R2) ADDC(R1,2,R1) CMPLTC(R1,10,R0) BT(R0,_L5) ST(R2,sum)This code has a 6 instruction loop that makes 0 data accesses; 5 loop iterations => 30 memory accesses. There are 6 additional memory accesses to initializes sum and i, and to store sum at the end of the loop. Total = 36.
Hand-assemble the following Beta assembly language program:
I = 0x5678
B = 0x1234
LD(I,R0)
SHLC(R0,2,R0)
LD(R0,B,R1)
MULC(R1,17,R1)
ST(R1,B,R0)
I = 0x5678
B = 0x1234
LD(R31,I,R0) 011000 00000 11111 0101 0110 0111 1000 = 0x601F5678
SHLC(R0,2,R0) 111100 00000 00000 0000 0000 0000 0010 = 0xF0000002
LD(R0,B,R1) 011000 00001 00000 0001 0010 0011 0100 = 0x60201234
MULC(R1,17,R1) 110010 00001 00001 0000 0000 0001 0001 = 0xA8210011
ST(R1,B,R0) 011001 00001 00000 0001 0010 0011 0100 = 0x64201234
BEQ R31 R31 offset = -1
011101 11111 11111 1111 1111 1111 1111
BEQ R31 R31 offset = 0
011101 11111 11111 0000 0000 0000 0000
foo = 0x100 BEQ R31 R17 offset = (0x100 - 0x1004)/4 = 0xFC3F
011101 11111 10001 1111 1100 0011 1111
Explain why PC-relative branch addressing is a good choice
for computers like the Beta that can encode only a "small" constant
in each instruction.
SUBC R22 R17 12 110001 10110 10001 0000 0000 0000 1100 = 0xC6D1000C
if literal = 0x8000 then new PC = 0x87654 + 4 - (8000 * 4) = 0x67658 if literal = 0x7FFF then new PC = 0x87654 + 4 + (7FFF * 4) = 0xA7654
Usage: SOB(Ra,label,Rc)
Operation:
literal = ((OFFSET(label) - OFFSET(current inst))/4) - 1
PC = PC + 4
EA = PC + 4*SEXT(literal)
Reg[Rc] = Reg[Ra] - 1
if (Reg[Ra]- 1) != 0 then PC = EA
As with branches in the Beta, the binary encoding of the SOB
instruction places the low-order 16 bits of the "literal" value in the
low-order 16 bits of the instruction. The designers of the Meta
implementation have used the Meta's ALU to perform the subtraction.
loop: ADD(R1,R2,R3)
SOB(R4,loop,R4)
Assuming the ADD instruction is placed in location 0x108 of memory,
what are the contents of the low-order 16 bits of the SOB instruction?
What would be the correct values for OP[2:0] in order to perform a
subtract (i.e., SUM = A - B)?
| Model | Clock Rate | Avg. clocks/Inst. |
|---|---|---|
| x | 40 Mhz | 2.0 |
| y | 100 Mhz | 10.0 |
| z | 60 Mhz | 3.0 |
[1] .macro LDC(const,Rx) {
LD(.+8,Rx)
BR(.+8)
LONG(const)
}
[2] .macro LDC(const,Rx) {
PUSH(R17)
BR(.+8,R17)
LONG(const)
LD(R17,0,Rx)
POP(R17)
}
[3] .macro LDC(const,Rx) {
ADDC(R31,const >> 16,Rx)
SHLC(Rx,16,Rx)
ADDC(Rx,const & 0xFFFF,Rx)
}
Kerry tries each definition on a few test cases and convinces herself
each works fine. The Quality Assurance team isn't so sure and
complains that Kerry's LDC implementations don't all work for every
choice of register (Rx), every choice of constant (const), and every
choice of code location.
int x[20], y; y = x[1] + 4;
CMOVE (4, R0)
LD (R31, x + 4, R0)
ADDC (R31, x + 1, R0)Address Contents (in hexadecimal) 0x100 0xC05F0008 0x104 0xC03F0000 0x108 0xE060000F 0x10C 0xF0210004 0x110 0xA4230800 0x114 0xF4000004 0x118 0xC4420001 0x11C 0x77E20002 0x120 0x77FFFFF9 0x124 0xA4230800 0x128 0x605F0124 0x12C 0x90211000
Address Contents Opcode Rc Ra Rb Assembly 0x100 0xC05F0008 110000 00010 11111 ADDC(R31, 0x8, R2) 0x104 0xC03F0000 110000 00001 11111 ADDC(R31, 0x0, R1) 0x108 0xE060000F 111000 00011 00000 ANDC(R0, 0xF, R3) 0x10C 0xF0210004 111100 00001 00001 SHLC(R1, 0x4, R1) 0x110 0xA4230800 101001 00001 00011 00001 OR(R3, R1, R1) 0x114 0xF4000004 111101 00000 00000 SHRC(R0, 0x4, R0) 0x118 0xC4420001 110001 00010 00010 SUBC(R2, 0x1, R2) 0x11C 0x77E20002 011101 11111 00010 BEQ(R2,0x128) * 0x120 0x77FFFFF9 011101 11111 11111 BEQ(R31,0x108) ** 0x124 0xA4230800 101001 00001 00011 not an opcode 0x128 0x605F0124 011000 00010 11111 LD(0x0124,R2) 0x12C 0x90211000 100100 00001 00001 00010 CMPEQ(R1,R2,R1) * The literal in instruction 0x11c is 0x2, so the corresponding label in Beta assembly is PC + 4 + 4*literal = 0x11c + 4 + 4*2 = 0x128 ** In instruction 0x120, SEXT(literal) = -7, so the corresponding label in Beta assembly is PC + 4 + 4*literal = 0x120 + 4 + 4*(-7) = 0x124 - 0x01C = 0x108
R2 = 8; /* R2 is used as a counter */ R1 = 0; loop: R3 = R0 & 0xF; /* R3 stores the current low nibble of R0 */ R1 = R1 << 4; R1 = R3 | R1; R0 = R0 >> 4; R2 = R2 - 1; if R2 == 0 goto done; goto loop; data: 0xA4230800 done: LD(data,R2); if (R1 == R2) R1=1; else R1=0;We can see that the code shifts R1 left by a nibble (4 bits) and ors it with the low nibble (R3) of the user's entered password (R0). It then shifts the user's password right by a nibble and loops back to the beginning. It does this a total of 8 times. The net effect is to reverse the order of the nibbles in R0 and to store this into R1. The result is then compared to 0xA4230800. Therefore, in order for the entered password to be accepted, it must be the nibble-reversed version of 0xA4230800. Thus, the "passnumber" required to enter is 0x0080324A