-2

Can someone please tell me why do i have errors in this?? The error says unaligned address at the sdc1. It seems pretty good to me. Could it be from the rest of the code?

la $a1, A

#Ask for A(1,1)
li  $v0 , 4
la  $a0 , a11       
syscall

#Read double
li  $v0 , 7
syscall

#Store double
sdc1    $f0 , ($a1)
Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
Christina J
  • 79
  • 2
  • 8
  • What is "seem pretty good to me"? What is actual `a1` value before executing `sdc1` instruction? Does that value work as aligned (enough for `sdc1`) address, pointing into writeable memory? The `sdc1/ldc1` instructions need the memory aligned to 8-byte boundaries (bottom three bits of address must be zero). Check that in debugger and then check why the `A` address is not in `a1`, or if it is, why it is not 8-byte aligned. – Ped7g Aug 18 '17 at 13:44
  • I'd *really* like to know why this would ever be tagged `double-submit-problem`. – EOF Aug 18 '17 at 15:13

1 Answers1

0

I'm not MIPS expert, but IIRC, two things should help you:

1)

a0-a3 are "argument" registers, which may be modified by sub-calls according to calling convention, you don't want to store there some pointer value which you will use over some longer period.

For that registers s0-s7 are better, as those should be preserved by any routine, i.e. your own code should first store them on the stack for example (and restore them to original value before returning), before modifying it to hold your A1 address, but then any syscall or any correctly written sub-routine should keep the s? value preserved.

If you have piece of code, which doesn't call anything, you may use t0-t7 registers for temporary values, which you can modify freely (or even a0-a3, as subroutine may modify the argument values).

2)

sdc1 instruction needs the address to be 8-byte aligned (lowest three bits zeroed).

If you have dynamically allocated memory from heap, unsure about it's alignment, allocate +8 bytes more, and adjust the pointer of allocated memory by ((ptr+7)&(-8)), which will clear the lowest three bits (also keep around the original pointer value, as you will probably need it to deallocate that memory). Then used the aligned value as start of your buffer for double values.


Just to make sure you understand what is meant by "alignment". An computer address is "aligned" by 2/4/8/... bytes, if its value can be divided by that number without remainder. So address 800 is 8-byte aligned (800/8 = 100), but 804 is not 8-byte aligned (804/8 = 100.5). As usually the alignment of power of two is required in computers, and values are binary encoded in bits, there's no need to do actual division of value to verify it's alignment. With binary encoding number of cleared lowest bits defines it's alignment by powers of two. No clear bit = odd number (aligned by 1 only), the lowest bit clear = even number (aligned by 2), two bits clear = divisible by 4 = aligned by 4. So for 8 byte alignment the bottom three bits has to be zero. If you have address in hexadecimal formatting, the last digit must be either 0 or 8 (0000 or 1000 in binary). Any other hexadecimal digit has some bit set in the lowest three, i.e. such address is not divisible by 8, so it's not properly aligned for sdc1 instruction.

So if you understand that paragraph above, you can very quickly check if some address is valid in debugger, just by seeing the value in the register in hexadecimal formatting (almost every debugger shows values in hexadecimal by default, as it makes it very easy for human to see particular bits and bytes, in decimal formatting you would have to calculate remainder of division by 8 to be sure).

As how to define the A array in aligned way... as you didn't show how you define it, it's hard to tell. Let's guess you use one of MARS/SPIM MIPS emulators for these exercises. Then you can allocate 800 bytes aligned to 8-byte boundary by this code:

        .align 3      # align next data item to 2^3 (= 8) boundary
array:  .space 800    # allocate 800 bytes of space
Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • You may check this answer for another explanation of `.align` directive of some MIPS assemblers: https://stackoverflow.com/a/41359823/4271923 – Ped7g Aug 18 '17 at 15:16