0

First question: I know that by definition the instruction Beq has at first two registers and then a label where to jump to. However, when I run Mars compiler I get that for example: "beq $s6, 1, Lable" is running well. I would like for explanation if this command is still valid, and if not so, then why is it compiled.

Second question - for this question I have the following code:

psudo code: 

   Main: 
   { 
       Func(3,12,0x12)
   }


   Func1(a,b,c)
   {
       sum=a+b+c
      Func2(sum,a,b,c)
       Return sum
   }
   Func2(sum,a,b,c) 
   {
       sum=sum*(a+b+c)
       Return (sum+1)
   }


Main: 
addi $a0, $0, 3 #first function input a0=3
addi $a1, $0, 12 #second function input a1=12
addi $a2, $0, 0x12 #third function input a2=0x12
jal Func1 #jump to function1 with those input virables. 
add $s2 $0, $v0 #store the result of func1 at $s2.
j break #go to break. 

Func1:
addi $sp, $sp, -16 #allocate memory for 4 registers
sw $a2, -12($sp) #restore a2 = c
sw $a1,  -8($sp) #restore a1 = b
sw $a0,  -4($sp) #restore a0 = a
sw $ra,   0($sp) #restore return address.

add $t0,$a0,$a1 #t0=a+b
add $t0,$t0,$a2 #t0+=c

add $a0, $0, $t0 #store the result of a+b+c at $a0.
lw $t1,  -4($sp) #restore t1=a
add $a1, $0, $t1 #a1=t1 
lw $t2,  -8($sp) #restore t1=b
add $a2, $0, $t2 #a1=t2
lw $t3,  -12($sp) #restore t1=c
add $a3, $0, $t3 #a1=t3
jal Func2 #jump to func2 with the input numbers a0,a1,a2,a3.
lw $ra, 0($sp) #change the return adress to the main function calling. 
addi $sp, $sp, 16 #deallocate memory.
jr $ra #return

Func2:
add $t0, $a1, $a2 #t0=a+b
add $t0, $t0, $a3 #t0+=c
mult $a0, $t0 #sum*(a+b+c)
mflo $a0 #storing result in $a0
addi $v0,$a0,1 #storing result+1 at the return function variable $v0
jr $ra #return 
break: 

Now is this code valid? because it is complied too in Mars, however, I have noticed that both storing the word and loading, it is with - instead of +, is it valid considering MIPS instructions? Thanks!

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Chopin
  • 113
  • 1
  • 10
  • MIPS's only addressing mode is register + *sign-extended* 16-bit immediate. So yes, negative offsets from registers are valid. Or do you mean accessing stack memory below the stack pointer? I'm not sure if any standard MIPS calling convention has a red-zone or not. If not, it's not a safe place to keep your data, but it is of course a valid machine instruction. The CPU (and the assembler) don't care if you write a buggy program, as long as it consists of valid machine instructions. – Peter Cordes Jun 25 '21 at 07:32
  • 1
    `beq $reg, 1, label` isn't a valid machine instruction, but MARS has extensive support for "pseudo-instructions", which you can disable. Look at the disassembly after you assemble to see which instructions MARS used; the real machine instructions are right there in the GUI. – Peter Cordes Jun 25 '21 at 07:33
  • @PeterCordes You are saying that doing so: sw $a2, -12($sp) #restore a2 = c sw $a1, -8($sp) #restore a1 = b sw $a0, -4($sp) #restore a0 = a sw $ra, 0($sp) #restore return address. lw $t1, -4($sp) #restore t1=a lw $t2, -8($sp) #restore t1=b lw $t3, -12($sp) #restore t1=c is valid, even if there is a minus instead of a plus? – Chopin Jun 25 '21 at 07:34
  • @PeterCordes Oh, I didn't know that Mars works that way. – Chopin Jun 25 '21 at 07:36
  • @PeterCordes Just to sum it up, you are saying that the command of the first question isn't valid, and the code of the second question is valid. Right? – Chopin Jun 25 '21 at 07:48
  • The `beq` with one argument as constant 1 is a valid pseudo instruction that is expanded by the assembler into multiple machine code instruction. If you would look at the machine code instructions that result, in the simulator, you'll gain some understanding. MARS also has a help system that differentiates between real assembly instructions and pseudo instructions: you might take a look at it. – Erik Eidt Jun 25 '21 at 15:10
  • As for the `sw rr, -xx(sp)` that is perfectly legal machine code instruction, but very bad form to use storage that is below the stack pointer. This code is in error. It is allocating stack space, but then not hitting that allocated space (except for `$ra`). If `Func1` were to call another function that uses stack space, `Func1` would not find its memory stored values to be as expected. However, `Func1` (a) doesn't call any other function that uses stack space, and (b) doesn't rely on that storage after a call anyway. – Erik Eidt Jun 25 '21 at 15:12
  • As it stands `Func1` is both inefficient and incorrect. It should not use storage below the stack pointer (incorrect), and, using memory to shuffle the parameters is unnecessary, since they can simply be moved from one register to another -- provided they are moved in a logical order. – Erik Eidt Jun 25 '21 at 15:21

0 Answers0