-2

Here's the high-level function: J[6] = K[d-e]

d = $t0, e = $t1, J = $s1, K = $s2, final result goes in $s4

So far I have:

lw $t2, 24($s1) #Load J[6] into $t2
sub $t3, $t0, $t1 #Subtract e from d to $t3

What I know I can't do is lw $t4, $t3($s2) but I'm not sure how to translate K[$t0 - $t1].

cocoakrispies93
  • 45
  • 1
  • 11
  • 1
    You know what you cannot do but what you would like to do. So, if you cannot do it in one instruction as you would like, then use several instructions. You know that you can dereference a register, so make one that has d-e plus the address of K. Use as many instructions as you need until you have a single register to dereference. – Erik Eidt Sep 18 '21 at 04:52
  • Even if `$t3($s2)` was legal, you didn't scale it by the element-size; you're going to want an `sll`. Also, you don't need to load from `J[6]`; it's a write-only operand in that that high-level statement. – Peter Cordes Sep 18 '21 at 04:58
  • The code in the question [C to MIPS assembly confusion](https://stackoverflow.com/q/38472150) includes the answer to this (and not much else). The answer for why it's right isn't a super clear explanation, unfortunately, so I didn't upvote it, so I can't mark this question as a duplicate of it. But you can always look at C compiler asm output yourself: [Is there a way to use gcc to convert C to MIPS?](https://stackoverflow.com/a/63386888) – Peter Cordes Sep 18 '21 at 05:02
  • The problem with that answer is there are lines with statements that haven't been discussed in class yet that I can't use: ```lui $2, 0x002B ori $2, $2, 0xCBCC addu $12, $12, $15 ``` @PeterCordes – cocoakrispies93 Sep 18 '21 at 14:35
  • @Peter What does scale by element size mean? – cocoakrispies93 Sep 18 '21 at 14:40
  • @ErikEidt How do you know what d-e plus the address of K is if K's address is at d-e? – cocoakrispies93 Sep 18 '21 at 14:41
  • `K` itself has its own address (it is not at d-e); K's value is the base address of the array, wherever that has been located. In this case, it is given as being the value in `$s2`. – Erik Eidt Sep 18 '21 at 14:43
  • Okay thanks! That clears a lot up – cocoakrispies93 Sep 18 '21 at 14:48
  • @ErikEidt how does adding two addresses come up with a product that's an address, wouldn't these all be values? – cocoakrispies93 Sep 18 '21 at 15:07
  • 1
    We don't add two addresses, that would be nonsense. We add addresses to indexes that produces another address. We can subtract two addresses to get an index. But we cannot add two addresses to get anything sensible. – Erik Eidt Sep 18 '21 at 15:11
  • 1
    Think of the difference between a date/time and a duration. We can add a duration (1 day) to a date/time (May 4th) to get a new date/time (May 5th); we can add two durations (1 day + 2 days) to get a new duration (3 days), but we cannot add two date/times -- doesn't make sense (May 4th + May 5th = ???). Though we can subtract two date/times to get a duration (May 6th - May 4th = 2 days). – Erik Eidt Sep 18 '21 at 15:12
  • And yes, all these are values: address, index, date/time, duration. We need to consider the types values have to manipulate them in meaningful ways, and to prevent doing things that don't make sense (even though the processor would happily do it). – Erik Eidt Sep 18 '21 at 15:17
  • In summary, try to identify the types of each of the values you are working with. For example, in `J[6]`, we have `J` and `6`. One is an array (an address) and the other is an index. – Erik Eidt Sep 18 '21 at 15:22
  • Okay, so that's why d-e is the index, and since K starts at the i=0 index, if I subtract d-e to get i and then add that to the i=0 index, I get the address of K? I think I understand that, my new problem is then I wanted to put K which was $s2 into J which was $t2 using a store word, ```sw $t2, 0($s2)``` but I don't know what the coefficient of ($s2) would be, I've only ever seen it as ```32($s2)``` because coincidentally everything I've seen involved 8's and I'm assuming it's 8 times 4 for 32 bits but I'm not sure. I put a zero because there's no immediate or index I can see @ErikEidt – cocoakrispies93 Sep 18 '21 at 15:45
  • `K` at high level is an entire array, but at the low level it is one single address. Yes, it is the same address/value as the location of element `K[0]`. Note that `K` and `J` are different values b/c they are separate arrays each with their own memory locations. So, element `K[d-e]` has a location of index `d-e` within array `K`. The coefficient is `d-e`. While we can do constant coefficients in MIPS in one instruction, we cannot do a dynamic coefficient in one instruction in MIPS, so you have to use several instructions.. What arithmetic would combine address `K` with index `d-e`? – Erik Eidt Sep 18 '21 at 16:05
  • Sorry, so my previous instruction prior to the ```sw $t2, 0($s2)``` is the addition of K + d-e, so ```add $s2, $s2, $t3``` and then I was left with this ```sw $t2, ?($s2)``` because I got stuck on J = K after all of the previous statements. I was saying that I've only see that question mark be 32 so I've never seen it as a different coefficient and can't figure out what determines what it is, but since coincidentally 8 keeps being used a lot, I'm assuming it's 4 bits times 8 registers making 32 bits and that's why I'm always seeing ```sw $t2, 32($s2)```. But there's no immediate @ErikEidt – cocoakrispies93 Sep 18 '21 at 16:21
  • MIPS needs a coefficient, but if you don't then use the additive identity, 0. Can also be written without the 0, as in simply `($t0)` in assembly, though the MIPS assembler will of course, assume 0, since a constant coefficient is required in the machine code instruction. – Erik Eidt Sep 18 '21 at 16:24
  • FWIW, when you do the add to combine `K` and `d-e`, if you return the result of that addition to the register that holds `K`, then that will wipe out the original `K`, so better to send the result somewhere else. – Erik Eidt Sep 18 '21 at 16:25
  • Okay thanks I think I got it! – cocoakrispies93 Sep 18 '21 at 16:26
  • Ok, your next will be about scaling. Each 4 byte integer takes 4 bytes. MIPS, like modern computers, is byte addressable, which means that every byte has a unique address. To get from K[0] to K[1] is a difference of 4 byte addresses. Scaling is the job of converting an index into a byte offset. It is basically multiplication by 4, generally done shifting left by 2 bit positions (which does *4). You will have to keep your scaled values separate from unscaled values -- they are different types. Address arithmetic must be done with scaled index values, when dealing with multibyte elements. – Erik Eidt Sep 18 '21 at 16:29
  • So, `K[d-e]` requires: (1) doing d-e, (2) scaling this index into a byte offset, (3) adding byte offset and base array address, then that, finally, can be dereferenced using store or load. – Erik Eidt Sep 18 '21 at 16:32

2 Answers2

5

To start: to translate this statement into assembly,

J[6] = K[d-e];

first, let's look at it in Three Address Code, which requires us to tease out the direction and order of the smaller operations:

x1 = d-e             # store subt
x2 = x1 * 4          # scaling by element size
x3 = K + x2          # byte address pointer arithmetic
x4 = *x3             # dereference to fetch K[d-e]
x5 = J + 24          # compute byte address of J[6]
*x5 = x4             # store into J[6] the value of K[d-e]

(Note that three address code never reuses temporary variables, though in the MIPS equivalent, that would be common to reuse/repurpose registers for temporary results (when the old temp value is no longer needed)).

Also MIPS can do the J[6]= without separately computing J+24, so x5 does not have to be computed.

The * operation, the C operator known as dereference, when it occurs on the right hand side of = assignment, it is done as a load instruction to fetch data from memory.  When it appears on the left hand side of an = assignment, that is done as a store instruction to store data into memory.


Next, let's look at the address computations and what MIPS can and cannot do.

You have the right idea with $t3($s2), but MIPS cannot do that.  It can only do constant indexing.

So, what does $t3($s2) represent?  It is the combination of a dynamic index with a base address, that results in an elemental address.

In this (not supported form) $t3($s2), how would these two values, $t3 and $t2, be combined?  By addition: we can add an index to a pointer and get a new pointer.

However, because MIPS is a byte addressable machine, addresses & pointers in MIPS refer to individual bytes.  A byte is an 8-bit datum.  So, when we use pointers and address on such a machine, these the type of such addresses and pointers is byte addresses.

When we use 32-bit words, these occupy multiple bytes, 4 x 8-bit bytes in fact for a 32-bit word.  When a 32-bit is the element of an array that word occupies 4 bytes, each of which has its own byte address, so it occupies 4 byte addresses as well.

Similar to how the whole array is sometimes referred to by the address of where it starts (its index 0), a whole element (4 bytes) is referred to by the address of its lowest byte.  To move from one element to the next, means moving by 4 byte addresses.

So, given an index, we have convert that index into a byte offset, which in this context, is called scaling.  The scale factor is the same as the size of the elements in the array, here an integer array, so 4 bytes per element.  The scale factor is thus 4.

So, what we want is more like $t3*4($s2), but of course MIPS cannot do this either.  But using separate instructions, MIPS can multiply by 4, and MIPS can also add dynamic values together.  Once these are done, we can use the constant coefficient dereference form that MIPS does provide — with the additive identity, since we have already computed the complete address.


There are two ways to do: K[i+1]:

  1. Add i and 1, then multiply that result by 4, then add K and use zero for the offset in a load or store instruction.

  2. Multiply i by 4, then add K and use 4 for the offset in the store instruction.

Form 2 uses a non-zero offset value of 4, which is the +1 scaled by *4.  This happens to be 1 instruction shorter than solution 1.


How to multiply by a small constant like 4, let's say the number to multiply is in $t0, and the result is desired to be in $t1:

  1. Add number to itself 4 times, using the target to accumulate the result:
    add $t1, $t0, $t0     # t1 = t0 + t0 = t0 * 2
    add $t1, $t1, $t0     # t1 = t1 + t0 = t0 * 3
    add $t1, $t1, $t0     # t1 = t1 + t0 = t0 * 4
  1. Add number to itself once, then add that number to itself once
    add $t1, $t0, $t0     # t1 = t0 + t0 = t0 * 2
    add $t1, $t1, $t1     # t1 = t1 + t1 = t0 * 2 + t0 * 2 = t0 * 4
  1. Shift the number left by 2 (binary) places
    sll $t1, $t0, 2       # t1 = t0 << 2 = t0 * 4
Erik Eidt
  • 23,049
  • 2
  • 29
  • 53
  • In my class we haven't learned multiplication yet, my professor advised to use adding in order to get to the multiplication. Would scaling be ```sw $t2, 4($t4)``` and ```sw $s4, 4($t2)```? Or would it be add ```$t4, $t4, $t4``` four times? @ErikEidt – cocoakrispies93 Sep 18 '21 at 17:51
  • See my addendum. – Erik Eidt Sep 18 '21 at 17:57
  • We haven't learned sll so I can't use that, can sll be done through adding or subtracting? I've revised my answer to my question, I'm not sure if it's correct or not other than the sll @ErikEidt – cocoakrispies93 Sep 18 '21 at 18:31
  • 2
    These three ways are equivalent -- they achieve the same results and only differ by the number of instructions (and how overflow is handled, but that is another matter). I didn't mention using `mul`, but that would also be equivalent. – Erik Eidt Sep 18 '21 at 18:35
  • 1
    @cocoakrispies93, `my professor advised to use adding in order to get to the multiplication`, then that should've been stated in the original question. It's too late to fundamentally change a question once people have provided answers. – Elliott Sep 18 '21 at 18:59
  • @Elliott, that didn't fundamentally change the question and because I was asking the question in the first place I didn't know what the suggested answers were going to be in the future ? I just know what's been taught and I'm not sure how I was supposed to specify not to use sll or something similar because I've never heard of it. I couldn't say I can't use multiplication to scale because I also haven't heard of that in that phrasing, like I said, the professor has deliberately not taught multiplication in assembly yet. – cocoakrispies93 Sep 18 '21 at 22:32
0

This is just me working out my own homework problem with the help of advice from commenters. Earlier revisions of this answer included a wrong version that loaded from J[6] instead of storing and overuse of temps.

This is the pseudo-code:

x1 = d-e             # store subtraction
x2 = x1 * 4          # scaling by element size
x3 = K + x2          # byte address pointer arithmetic

x4 = *x3             # dereference to fetch K[d-e]
x5 = J + 24          # compute byte address of J[6]
*x5 = x4             # store into J[6] the value of K[d-e]

This is the attempted implementation, the only issue is the last two steps, in the question it specifies $s4 to hold the final answer, but J[6] still needs to be overwritten because that's the assignment statement:

sub $t3, $t0, $t1  #Subtract d-e to $t3, next step is multiply by 4 to scale
add $t5, $t3, $t3  # t5 = t3 + t3 = t3 * 2
add $t5, $t5, $t5  # t5 = t5 + t5 = t3 * 4  = (d-e)*4 as a byte offset
add $t3, $s2, $t5  #Add d-e index plus K's 0th index to get final index into $t3 temp

lw $t3, 0($t3)     #Load K's pointer based on index into the value of K
sw $s1, 0($t3)     #Store the value of K into J[6]
sw $s4, 24($s1)    #Store J[6] into $s4, it's 24 because index 6 x 4-byte array element size

Another possibility for the last two is this, I'm not entirely sure:

lw $s1, 24($s1)    # compute byte address of J[6], its old value doesn't matter
sw $s1, 0($t3)     #Store the value of K into J[6]
sw $s4, 24($s1)    #Store J[6] into $s4, it's 24 because index 6 x 4-byte array element size
cocoakrispies93
  • 45
  • 1
  • 11
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/237386/discussion-on-answer-by-cocoakrispies93-how-to-convert-a-high-level-language-sta). – Samuel Liew Sep 23 '21 at 01:30
  • Okay how do I get to that chat without that link? @SamuelLiew – cocoakrispies93 Sep 25 '21 at 18:38