newprint
newprint

Reputation: 7090

Questions about MIPS instructions in the code

I have a question about several MIPS instruction in the code below
1. addi is an arithmetic instruction, what it's purpose ?
2. why there is single nopafter j and beq, but there are multiple nops after addi ?
Thanks !

if(a==b)  x=3; /* simple C code */
else      x=4;
y=5;  

       lw   $1,a       # possible unoptimized assembly language
       lw   $2,b       # no ($0) shown on memory access
       nop             # wait for b to get into register 2
       nop             # wait for b to get into register 2
       beq  $1,$2,lab1
       nop             # branch slot, always executed *********
       addi $1,4       # else part
       nop             # wait for 4 to get into register 1
       nop             # wait for 4 to get into register 1
       sw   $1,x       # x=4;
       j    lab2
       nop             # branch slot, always executed *********    
lab1:  addi $1,3       # true part  
       nop             # wait for 3 to get into register 1
       nop             # wait for 3 to get into register 1
       sw   $1,x       # x=3;  
lab2:  addi $1,5       # after if-else, always execute
       nop             # wait for 5 to get into register 1
       nop             # wait for 5 to get into register 1
       sw   $1,y       # y=5;

Upvotes: 1

Views: 4549

Answers (3)

markgz
markgz

Reputation: 6266

In a normal MIPS assembler addi $1,4 is shorthand for addi $1,$1,4, i.e. add 4 to $1. The normal shorthand to load a constant into a register is li $1,4 which the assembler usually translates into ori $1,$0,4. (Register $0 always contains zero.)

The instructor's example appears to be incorrect, unless a is known to be always zero. In that case, there are much better ways of implementing this code.

Upvotes: 1

old_timer
old_timer

Reputation: 71586

addi is "add immediate" it adds an immediate value (a constant, an integer) to the contents of a register. the other add variant(s) are register adding with registers.

The nops after addi and the descriptions make no sense at all from a mips perspective. Mips is well used for educational purposes and the particular implementation you are using or being taught might require time for the addi instruction to decode and execute and store the result to the register file before that register can be used as an input to another instruction. Normally the mips core (or any modern pipelined processor for that matter) will block the next instruction or use other solutions to short cut the result of one instruction that is the input to a following instruction.

it is not only the addi but also the lw where you see these nops used to delay time as the comments say for the result to be stored in the register.

At a minimum think of the basic steps, fetch, decode, execute, store results. this code seems to be allowing time for at least some of these steps to complete even though a real mips wouldnt need to.

Having the delay slot after a branch is very much a mips thing (sure others do it to but it is more rare than common). The easy way to do it is to just put a nop after every branch or jump and waste the cycle. Eventually you will learn when you can take one of the instructions before the branch and put it after, otherwise using a nop if you cant find one.

In general the code looks fine. for the addi instructions to work so that the code is a representative of the C code, the addi really needs to use register 0 which is always a zero. Addi takes a register and an immediate adds them together and puts the result in a different register, there are two registers for an addi and one constant...The code you have only shows one register. For all of the uses of addi in that code if you think of it this way:

addi $1,4 
changes to 
addi $1,$0,4
register $0 is always zero so this instruction really means
$1 = 0 + 4 = 4
$1 = 4

I know the mips instructions from a formal perspective and from a machine code perspective, perhaps addi $1,4 is a shortcut that represents the more formal addi $1,$0,4. Assemble the code then examine the machine code for that instruction and you will probably see the two registers $1 and $0 with the immediate 4.

Mips does not have a mov instruction where you can move a whole register sized immediate in one shot. The lui instruction is used to put bits in the upper half of a register and zeros in the lower half. Lui followed by an addi or an ori can be used as a team to load an immediate. Or if the upper bits are zeros then addi or ori with register 0 ($0) can be used to set the lower bits in a single instruction. For this asm to represent the C code the latter must be the case.

Upvotes: 3

Preet Sangha
Preet Sangha

Reputation: 65556

I don't know MIP assembler I'm guessing on the following (after reading the Wiki article MIPS Architecture)

  1. the writer knows that a = 0, thus $1 = 0, thus addi $1, 4 sets the $1=4 ready for the sw to x.
  2. the NOPs make no sense - unless the writer knows that the the instructions are paralleled and thus inserts clock cycle waits to make sure the previous instructions complete.

Is there more context to the code (ie the set up of x and a, b etc.)

Upvotes: 1

Related Questions