1

If you are given:

calc (int b) {
return b - 2;
}

How would it be converted to MIPS?

I've considered the following:

addi $v0, $a0, -2
jr $ra
***********************
jr $ra
addi $v0, $a0, -2
***********************
addi $v0, $a0, 2
jr $ra 
***********************
lw $v0, 0($a0)
addi $v0, $v0, -2
jr $ra

I'm just learning functions in MIPS and would appreciate advice. Is there any point in using the 'lw' instruction in this case?

  • 4
    Andre, How parameters are passed in your ABI variant, where return address is stored? What is the version of MIPS? Does it have "branch [delay slot](https://en.wikipedia.org/wiki/Delay_slot)"? LW is for loading data from RAM memory: https://en.wikipedia.org/wiki/MIPS_architecture#Loads_and_stores – osgx Sep 30 '17 at 06:21

1 Answers1

1

Your results are correct, at least the first one. According to here your first answer of:

addi $v0, $a0, -2
jr $ra

is correct. It uses the least amount of instructions which will increase execution speed, not to mention that using immediate instructions reduce fetches from memory. Look at the table in the link and will tell you that:

  • $v0 is the register of where the first return value from a function should go.
  • $a0 is the register of the first input parameter to use when calling functions.
  • $ra is the register holding the return address from a previous jump instruction.

So someone wanted to call your assembly function it would look like:

int x = calc(5); // This line is the `C` equivalent and not part of assembly code.

Assembly would be:

li $a0, 5  # Load immediate the value 5 into register $a0.
jal __calc # Jump to the sub routine '__calc' and store return address in $ra.
           # Result will now be in $v0.
...

__calc:
  addi $v0, $a0, -2
  jr $ra 

Try to stay away from instructions like lw if you can. They go out to RAM and fetch memory which is super slow compared to keeping values in the CPU's registers.

user2205930
  • 1,046
  • 12
  • 26
  • I've noticed that some of the functions I am trying to write in MIPS, including this one, that when I use instructions like 'lw' or 'sw', that I receive an error. Usually the error message reads: "fetch address not aligned on word boundary". Does this mean anything in terms of you mentioning fetching values from RAM? Keep in mind I am using: ori $a0, $0, 5 to initialize $a0 to 5 for testing purposes. If I don't limit the value of $a0 do you think I might avoid errors using a 'lw' instruction? This is just out of curiosity, I'm already satisfied with your answer. –  Oct 01 '17 at 18:00
  • 1
    If you want a value in a register such as `5` in register `$a0` you can just use the 'load immediate` instruction `li`. `li $a0, 5` is the same as $a0 = 5. When using instructions like `lw` and `sw` require a register and RAM address. If you used `lw $a0, 5` that is the same as saying load the contents of RAM at address `5` into `$a0`, the contents in RAM could be anything. The RAM address `5` may be restricted for kernel use, user space memory starts higher in RAM addresses which would result in fetch errors. – user2205930 Oct 01 '17 at 18:19
  • 1
    The issue of 'fetch address not aligned on WORD boundaries' is another issue. A WORD is the register size of the CPU, assume 32-bit in your case. This means that when reading and writing to RAM the address you provide must be 32-bit aligned. Without knowing the exact details of your setup this is the best answer I can give. Usually any RAM address is valid. – user2205930 Oct 01 '17 at 18:26