0
votes

I am new to assembly coding and I came across a problem that says to transfer the following C code to MIPS assembly.

b[8] = b[i-j] + x ;

and variables i,j,x are in registers 7,4 and 15 and base address of array b is in 2,870,220 decimal.

I came up with the following solution

 lui $2, 0x002B
 ori $2, $2, 0xCBCC
 sub $3, $7, $4
 add $3, $2, $3
 lw $12, 0($3)
 addu $12, $12, $15
 sw $12, 32($2) 

but when I checked the answer, there was one additional line of

sll $3, $3, 2 

after the subtract instruction.

Could someone please explain why do we need to multiply the content of register $3 by 4 ?

1
the array is word (32 bit) sized not byte sized?old_timer
The problem does not specify anything about the array.David Karakolyan
it is probably word sized. actually I forget the syntax for mips, lw is load word yes? a 32 bit thing? what is load byte? lb? if lw is a 32 bit load then you need to align the offset to a word thus the multiply by 4 to get the offset to the address not the indexold_timer

1 Answers

0
votes

I'll give an illustration.

Let's say we have these 5 bytes stored in memory locations 0x00000000 to 0x00000004 (as an example, I'm disregarding memory maps):

| 0x27 | 0x82 | 0x97 | 0x42 | 0x11 |

When loading a word at memory address 0x00000000, it would give you the 32-bit word 0x27829742 because it concatates the next 4 bytes from the base address.

At memory address 0x00000001, however, you get 0x82974211.


I'm thinking that this misunderstanding is coming from how operator[] is implemented in arrays, so I'll try to expand on that. Consider the following C code:

int arr[3] = { 1, 3, 5 };
printf("%d\n", arr[2]); // print third element

When accessing arr[2], it has to take into account the size of the elements of the array. Assuming that the int standard is 32bit (4byte), you would get the following code during compile time:

int arr[3] = { 1, 3, 5 };
printf("%d\n", *(arr + (2 * sizeof(int)))); // print third element

In this case, it offsets the base pointer of the array by an integer's worth of bytes multiplied by the index being accessed, and then deferenced to get the specified element.

In conclusion:

Memory blocks are aligned in 8bit bytes, not 32bit words.