Moving ahead one more jump in our C to ASM exercises. This time we are bringing in the handling of arrays and shifting. Since this is not the same as the previous 3 exercises, I am bringing load/store instructions back into the writeup. I am going to keep up with the ARM conversions even though a MIPS asm program is looking tempting again. However, I know there are later exercises where I will be writing programs.
Per Exercise Instructions:
f,g,h,i,j assigned to $s0…$s4
address A in $s6
address B in $s7
ARM Assumptions:
f,g,h,i,j assigned to r4,r5,r6,r7,r8
address of A in r11
address of B in r12
a) f = -g - A[4];
b)B[8] = A[i-j];
2.4.1 For the C statements above, what is the corresponding MIPS assembly code?
a)
f = -g - A[4];
MIPS
|
Comment
|
ARM
|
lw $t0, 16($s6)
add $t0, $t0, $s1
sub $s0, $zero, $t0
|
#load 4x4 into temp 0
#16($s6) is 4th address in A
#add A[4], g = A[4] + g
#f = 0 - $t0 = 0-(g + A[4])
|
ldr r0, [r11, #16]
add r1, r0, r5
sub r4, #0, r1
|
b)
B[8] = A[i-j];
MIPS
|
Comment
|
ARM
|
sub $t0, $s3, $s4
sll $t0, $t0, 2
add $t0, $t0, $s6
lw $t0, 0[$t0]
sw $t0, 32[$s7]
|
#load i - j into t0
#shift left 2 to *4
#to adjust to register location
#add t0 to &A
#load value A[i-j] - into t0
#store t0 into B[8]
|
sub r0, r7, r8, lsl#2
add r0, r0, r11
ldr r0, [r0, #0]
str r0, [r12, #32]
|
2.4.2 For the C statements above, how many MIPS assembly instructions are needed to perform the C statement?
a) 3
b) 5 (4 for ARM because ARM can combine an operand with an instruction - sub(s) Rd,Rn,<Operand2>)
2.4.3 For the C statements above, how many different registers are needed to carry out the C statement?
a) 1 temp, 2 savedb) 1 temp, 4 saved
ARM Assumptions:
f,g,h,i,j assigned to r4,r5,r6,r7,r8
address of A in r11
address of B in r12
Since theres not too much writing of my own code in the rest of this, I am going to translate the given MIPS code into ARM.
a.
MIPS
|
Comment
|
ARM
|
sll $s2, $s4, 1
add $s0, $s2, $s3
add $s0, $s0, $s1
|
#s2 = s4*2
#s0 = s2 + s3
#s0 = s0 + s1
|
lsl r6, r8, #1
add r4, r6, r7
add r4, r4, r5
|
b.
MIPS
|
Comment
|
ARM
|
sll $t0, $s0, 2
add $t0, $s6, $t0
sll $t1, $s1, 2
add $t1, $s7, $t1
lw $s0, 0($t0)
addi $t2, $t0, 4
lw $t0, 0($t2)
add $t0, $t0, $s0
sw $t0, 0($t1)
|
# t0 = f * 4
# t0 = &A[f]
# t1 = g * 4
# t1 = &B[g]
# f = A[f]
# t2 = &A[f+1]
# t0 = A[f+1]
# t0 = t0 + A[f]
# B[g] = t0
|
lsl r0, r4, #2
add r0, r11, r0
lsl r1, r5, #2
add r1, r12, r1
ldr r4, [r0, #0]
add r2, r0, #4
ldr r0, [r2, #0]
add r0, r0, r4
str r0, [r1, #0]
|
2.4.4 For the MIPS assembly instructions above, what’s the corresponding C statement?
a)
h = (j << 1) //j*2
f = h + i
f = f + g
compacts to
f = (j<<1)+i + g
b)
sll $t0, $s0, 2 # $t0 = f * 4 --- integers 4 bytes
add $t0, $s6, $t0 # $t0 = &A[f]
sll $t1, $s1, 2 # $t1 = g * 4
add $t1, $s7, $t1 # $t1 = &B[g]
lw $s0, 0($t0) # f = A[f]
addi $t2, $t0, 4 #$t2 = &A[f+1]
lw $t0, 0($t2) #$t0 = A[f+1]
add $t0, $t0, $s0 #$t0 = $t0 + f
sw $t0, 0($t1) #B[g] = $t0
f = A[f]
f = A[f+1] + f
B[g] = f
compacts to
f = A[f] + A[f+1]
B[g] = f
B[g] = A[f] + A[f+1]
2.4.5 For the MIPS assembly instructions above, rewrite the assembly code to minimize the number MIPS instructions (if possible) needed to carry out the same function.
a) I believe a has the fewest instructions it can possibly have, as there are three instructions preformed 1 multiply, 2 add.
b)
sll $t0, $s0, 2 # $t0 = f * 4 --- integers 4 bytes
add $t0, $s6, $t0 # $t0 = &A[f]
sll $t1, $s1, 2 # $t1 = g * 4
add $t1, $s7, $t1 # $t1 = &B[g]
lw $s0, 0($t0) # f = A[f]
addi $t2, $t0, 4 #$t2 = A[f+1]
lw $t0, 4($t0) #$t0 = A[f+1]
add $t0, $t0, $s0 #$t0 = $t0 + f
sw $t0, 0($t1) #B[g] = $t0
While this result was reached in the following problem, I found it to be applicable to this one as well. In ARM however, I believe we can reduce the number of instructions performed more-so.
mov r3, #4 #r3 = 4 so we can use mla
mla r0, r4, r3, r11 #r0 = r4 * 4 + r11
mla r1, r5, r3, r12 #r1 = r5 * 4 +r12
add r1, r12, r1
ldr r4, [r0, #0]
ldr r0, [r0, #4]
add r0, r0, r4
str r0, [r1, #0]
2.4.6
In both code examples we can remove one register by changing to the following:
a)
sll $s0, $s4, 1
add $s0, $s0, $s3
add $s0, $s0, $s1
b)
sll $t0, $s0, 2 # $t0 = f * 4 --- integers 4 bytes
add $t0, $s6, $t0 # $t0 = &A[f]
sll $t1, $s1, 2 # $t1 = g * 4
add $t1, $s7, $t1 # $t1 = &B[g]
lw $s0, 0($t0) # f = A[f]
addi $t2, $t0, 4 #$t2 = A[f+1]
lw $t0, 4($t0) #$t0 = A[f+1]
add $t0, $t0, $s0 #$t0 = $t0 + f
sw $t0, 0($t1) #B[g] = $t0
This whole exercise is one we went through thoroughly on the board, that being said, in the first instruction set, we forgot to add in the bit shift to adjust the address. I added it into this write up. Also, finding an opportunity to use the ARM’s optional operand was interesting. Haven’t had a chance to exploit that feature yet. In addition, this was the first application of mla in a instruction set for me. I had originally had an incorrect notation of using an arg instead of a register, this has since been corrected.
No comments:
Post a Comment