CSc 256 Final Fall 2016 NAME: Problem 1 (25 points) Translate the C/C++ function func() into MIPS assembly language. The prototype is: void func(int arg0, int *arg1); arg0-arg1 are in $a0- $a1 respectively. func() calls the function hash() with the following prototype: int hash(int arg0); arg0 is in $a0, the return value is in $v0. You don't have to write the function hash(). Make sure your code is efficient; points will be deducted for obvious inefficiencies. You must follow all MIPS register use conventions. int hash(int); void func(int arg0, int *arg1) { int temp; int i; temp = *arg1; for (i=arg0; i>=0; i--) { temp = temp + hash(arg1[i]); } if (temp < 0) break; *arg1 = temp; }
ANS: # temp $s0 # copy of arg1 $s1 # i $s2 func: sw $31, -4($sp) sw $s0, -8($sp) sw $s1, -12($sp) sw $s2, -16($sp) addi $sp, $sp, -16 move $s1, $a1 lw $s0, ($a1) # temp = *arg1; move $s2, $a0 # for (i=arg0; i>=0;i--){ blt $s2, $0, skip for: sll $t0, $s2, 2 # temp = temp + add $t0, $t0, $s1 # hash(arg1[i]); lw $a0, ($t0) jal hash add $s0, $s0, $v0 blt $s0, $0, skip # if (temp < 0) # break; addi $s2, $s2, -1 bge $s2, $0, for # } skip: sw $s0, ($s1) # *arg1 = temp; addi $sp, $sp, 16 lw $31, -4($sp) lw $s0, -8($sp) lw $s1, -12($sp) lw $s2, -16($sp) jr $31
Problem 2: a) Consider this digital logic circuit: Fill out an equivalent truth table for the circuit. (12 points) ANS: X2 X1 X0 y 0 0 0 1 0 0 1 0 0 1 0 0 0 1 1 1 1 0 0 1 1 0 1 0 1 1 0 1 1 1 1 1
b) Fill out a truth table for this digital logic circuit. (8 points) ANS: X1 X0 MUX sel y 0 0 0 0 0 1 0 0 1 0 1 0 1 1 0 1
Problem 3: Refer to the MIPS single-cycle datapath in the sheets provided. Show the control signals for the MIPS instructions, in the table below. Note that some of the control signals have new names. (20 points) Hint: ALUOp control bits are 00 (force ALU to add), 01 (force ALU to subtract), 10 (follow operation specified by bits 5-0 of instruction word) [In Fall 2016, you are given a figure that s similar to Ch 7 Slide 27, or Figure 4.15 in your textbook. SelW is RegDst, SelX is ALUSrc, SelY is Branch, SelZ is MemToReg] a) beq MemRead MemWrite SelW SelX SelY SelZ ALUOp1 ALUOp0 RegWrite x 0 x 1 1 x 0 1 0 b) lw MemRead MemWrite SelW SelX SelY SelZ ALUOp1 ALUOp0 RegWrite 1 0 0 1 0 1 0 0 1
Problem 4 (20 points) Consider a 4 KB direct-mapped cache, with 32-byte blocks, with 32-bit memory addresses. a) Show how a memory address is divided into tag, index, and offset. Be clear about how many bits are in each field, and how each field is positioned within the memory address. # blocks = 4KB/32B = 128 offset is log32 = 5 bits index is log128 = 7 bits tag is 32 5 7 = 20 bits tag index offset b) For the cache in Part a, how many total bits are in the cache? Show work for partial credit. Each block has valid + tag + data; 1 + 20 + 32*8 bits Total # bits = # blocks * (1 + 20 + 32*8) = 128 * (1 + 20 + 32*8)
c) Suppose we run a program, and monitor the behavior of the data cache with the same dimensions as part a. The data cache is initially empty. The first four data addresses are (in order): 0x202c 0x120c 0x2020 0x520c Show the index for each address (in binary or hexadecimal), and state clearly whether each is a hit or a miss. 0x202c = 0..0 0010 0000 0010 1100 index = 0000 001 miss 0x120c = 0..0 0001 0010 0000 1100 index = 0010 000 miss 0x2020 = 0..0 0010 0000 0010 0000 index = 0000 001 hit (same index and tag as 0x202c) 0x520c = 0..0 0101 0010 0000 1100 index = 0010 000 miss (tag is different from 0x120c)
Short questions: 1) Trace this x86 assembly language fragment. Suppose %eax contains 3 and %ebx contains -1. Show the contents of %ebx when the label "end" is reached. subl %eax, %ebx movl $1, (%esp) cmpl %eax, %ebx jle go addl (%esp),%ebx jmp end go: subl (%esp),%ebx end: ANS: -5 Trace: subl %eax, %ebx ebx = ebx eax = -1-3 = -4 movl $1, (%esp) MEM[esp] = 1 cmpl %eax, %ebx jle go if (ebx <= eax) jump to go -4 <= 3, jump subl (%esp),%ebx ebx = ebx MEM[esp] = -4-1 = -5 2) Suppose the clock rate of a CPU is 600 MHz. What is the clock cycle time in nanoseconds? (If you don t want to do the algebra and work out the actual number, just write an expression that clearly gives the answer.) 1 sec = 600 * 10^6 cycles 1 cycle = 1 / (600 * 10^6) seconds = 10^-6 / 600 seconds = 1/600 microseconds = 1000/600 nanoseconds = 10/6 nanoseconds 3) [More short questions, maybe]
MIPS instructions op1, op2 are registers, op3 is register or constant cont[op1] means contents of op1 move op1, op2 cont[op1] = cont[op2] add op1, op2, op3 cont[op1] = cont[op2] + cont[op3] sub op1, op2, op3 cont[op1] = cont[op2] - cont[op3] mul op1, op2, op3 cont[op1] = cont[op2] * cont[op3] div op1, op2, op3 cont[op1] = cont[op2] / cont[op3] rem op1, op2, op3 cont[op1] = cont[op2] % cont[op3] not op1, op2 cont[op1] = not cont[op2] (bitwise) and op1, op2, op3 cont[op1] = cont[op2] and cont[op3] (bitwise) or op1, op2, op3 cont[op1] = cont[op2] or cont[op3] (bitwise) nand op1, op2, op3 cont[op1] = cont[op2] nand cont[op3] (bitwise) nor op1, op2, op3 cont[op1] = cont[op2] nor cont[op3] (bitwise) xor op1, op2, op3 cont[op1] = cont[op2] xor cont[op3] (bitwise) sll op1, op2, AMT cont[op1] = cont[op2] shift left logical by AMT bits srl op1, op2, AMT cont[op1] = cont[op2] shift right logical by AMT bits sra op1, op2, AMT cont[op1] = cont[op2] shift right arithmetic by AMT bits rol op1, op2, AMT cont[op1] = cont[op2] rotate left by AMT bits ror op1, op2, AMT cont[op1] = cont[op2] rotate right by AMT bits b label j label beq op1, op2, label bne op1, op2, label bgt op1, op2, label bge op1, op2, label blt op1, op2, label ble op1, op2, label beqz op1, label bnez op1, label bgtz op1, label bgez op1, label bltz op1, label blez op1, label la R, label li R, constant lw R,?? goto label goto label if (cont[op1]==cont[op2]) goto label if (cont[op1]!=cont[op2]) goto label if (cont[op1]>cont[op2]) goto label if (cont[op1]>=cont[op2]) goto label if (cont[op1]<cont[op2]) goto label if (cont[op1]<=cont[op2]) goto label if (cont[op1]==0) goto label if (cont[op1]!=0) goto label if (cont[op1]>0) goto label if (cont[op1]>=0) goto label if (cont[op1]<0) goto label if (cont[op1]<=0) goto label cont[r] = address of label cont[r] = constant cont[r] = M[ADDR]
lb R,?? lbu R,?? sw R,?? sb R,?? cont[r] = m[addr], sign-extended cont[r] = m[addr], zero-extended M[ADDR] = cont[r] m[addr] = low 8-bits of cont[r] if?? is a label, ADDR = address of label if?? is (R), ADDR = cont[r] if?? is constant(r), ADDR = cont[r] + constant if?? is label(r), ADDR = cont[r] + address of label mtc0 op1, op2 contents of coprocessor 0 register op1 = contents of MIPS register op2 mfc0 op1, op2 contents of MIPS register op1 = contents of coprocessor 0 register op2 Syscall usage: print an int $v0=1, $a0=int to be printed print a string $v0=4, $a0=address of string to be printed read an int $v0=5, input int appears in $v0 exit $v0=10 MIPS register names: $0 $1 $2,$3 $v0,$v1 $4 - $7 $a0 - $a3 $8 - $15 $t0 - $t7 $16 - $23 $s0 - $s7 $24 - $25 $t8 - $t9 $26 - $27 $k0 - $k1 $28 $gp $29 $sp $30 $s8 $31 $ra
0000 00ss ssst tttt dddd d000 0010 0000 add rd,rs,rt 0000 00ss ssst tttt dddd d000 0010 0010 sub rd,rs,rt 0000 00ss ssst tttt 0000 0000 0001 1000 mult rs,rt 0000 00ss ssst tttt 0000 0000 0001 1010 div rs,rt 0000 00ss ssst tttt dddd d000 0010 0001 addu rd,rs,rt 0000 00ss ssst tttt dddd d000 0010 0011 subu rd,rs,rt 0000 00ss ssst tttt 0000 0000 0001 1001 multu rs,rt 0000 00ss ssst tttt 0000 0000 0001 1011 divu rs,rt 0000 0000 0000 0000 dddd d000 0001 0000 mfhi rd 0000 00ss sss0 0000 0000 0000 0001 0001 mthi rs 0000 0000 0000 0000 dddd d000 0001 0010 mflo rd 0000 00ss sss0 0000 0000 0000 0001 0011 mtlo rs 0000 00ss ssst tttt dddd d000 0010 0100 and rd,rs,rt 0000 00ss ssst tttt dddd d000 0010 0111 nor rd,rs,rt 0000 00ss ssst tttt dddd d000 0010 0101 or rd,rs,rt 0000 00ss ssst tttt dddd d000 0010 0110 xor rd,rs,rt 0000 00ss ssst tttt dddd d000 0000 0100 sllv rd,rt,rs 0000 00ss ssst tttt dddd d000 0000 0110 srlv rd,rt,rs 0000 00ss ssst tttt dddd d000 0000 0111 srav rd,rt,rs 0010 00ss ssst tttt iiii iiii iiii iiii addi rt,rs,i 0010 01ss ssst tttt iiii iiii iiii iiii addiu rt,rs,i 0011 00ss ssst tttt iiii iiii iiii iiii andi rt,rs,i 0011 1100 000t tttt iiii iiii iiii iiii lui rt,i 0011 01ss ssst tttt iiii iiii iiii iii ori rt,rs,i 0011 10ss ssst tttt iiii iiii iiii iiii xori rt,rs,i 0000 0000 000t tttt dddd diii ii00 0000 sll rd,rt,i 0000 0000 000t tttt dddd diii ii00 0010 srl rd,rt,i 0000 0000 000t tttt dddd diii ii00 0011 sra rd,rt,i 1000 11bb bbbt tttt iiii iiii iiii iiii lw rt,i(rb) 1000 00bb bbbt tttt iiii iiii iiii iiii lb rt,i(rb) 1001 00bb bbbt tttt iiii iiii iiii iiii lbu rt,i(rb) 1010 11bb bbbt tttt iiii iiii iiii iiii sw rt,i(rb) 1010 00bb bbbt tttt iiii iiii iiii iiii sb rt,i(rb) 0000 01ss sss0 0000 iiii iiii iiii iiii bltz rs,i 0000 01ss sss0 0001 iiii iiii iiii iiii bgez rs,i 0001 10ss sss0 0000 iiii iiii iiii iiii blez rs,i 0001 11ss sss0 0000 iiii iiii iiii iiii bgtz rs,i 0001 00ss ssst tttt iiii iiii iiii iiii beq rs,rt,i
0001 01ss ssst tttt iiii iiii iiii iiii bne rs,rt,i 0000 00ss ssst tttt dddd d000 0010 1010 slt rd,rs,rt 0010 10ss ssst tttt iiii iiii iiii iiii slti rt,rs,i 0000 10ii iiii iiii iiii iiii iiii iiii j I 0000 00ss sss0 0000 0000 0000 0000 1000 jr rs 0000 11ii iiii iiii iiii iiii iiii iiii jal I 0000 00ss sss0 0000 dddd d000 0000 1001 jalr rd,rs 0000 0000 0000 0000 0000 0000 0000 1100 syscall
x86 assembly language syntax registers have prefix % constants have prefix $ %esp is stack pointer, points to top item in stack an operand can take one of four formats: constant e.g. $4 register e.g. %eax (register) e.g. (%eax) constant(register) e.g. 4(%esp) [instructions ending with l move 32-bit quantities] movl op1,op2 contents of op2 = contents of op1 pushl op push contents of op on the stack popl op pop top of stack into contents of op addl op1,op2 contents of op2 = contents of op2 + contents of op1 subl op1,op2 contents of op2 = contents of op2 - contents of op1 imull op1,op2 contents of op2 = contents of op2 * contents of op1 incl op contents of op2 = contents of op2 + 1 decl op contents of op2 = contents of op2-1 cmpl op1, op2 set condition codes according to result of (op2 - op1) je jump if == jne jump if!= jg jump if > jge jump if >= je jump if == jne jump if!= jl jump if < jle jump if <= jmp jump always jz jump if == 0 jnz jump if!= 0 call label label ret return address pushed on stack, jump to return address popped off top of stack