How to understand the opcode mips pseudo instruction move? - mips

found an explanation of the pseudo instruction
Move (move)
The move pseudo instruction moves the contents of one register into another register.
move $1, $2
translates to
add $1, $2, $0
Here is the code.
25f0a003 move fp, sp
but add opcode is like this.
31-26 special 0x000000
25-21 rs it should be 0x1d
20-16 rt it should be 0x0
15-11 rd it should be 0x1e
10-6 0 it should be 0x0
5-0 add it should be 0x32
but the opcode is different.

I'm not sure where you got the explanation you quoted in your question, but it's up to the assembler to decide how to implement pseudo-instructions.
The word 25f0a003 doesn't make sense as a MIPS instruction, but if we swap the bytes around to 03a0f025 then we get:
0000 0011 1010 0000 1111 0000 0010 0101
=>
000000 11101 00000 11110 00000 100101
=>
or $30, $29, $0
=>
or $fp, $sp, $zero
So in this case, the assembler you used translated move $fp, $sp into or $fp, $sp, $zero.

Related

How to convert / encode a negative number as an immediate in MIPS machine code

I want to change this instruction to binary or machine code:
addi $s3, $s1, -1000.
I know how to encode the opcode, rs, and rt, but I have no idea how to convert -1000 to binary.
I know how to get 1's complement and 2's complement. But i don't know how to express it in this I type instruction.
I just don't know how to express -1000 into last 16 digits as binary number.
since 1000(decimal) is 0000001111101000 in 16 digit.
1's complement is 1111110000010111
+1
= 1111110000011000 2's complement
so the answer for the whole instruction is
001000 10001 10011 1111110000011000
addi rs rt immediate
Is this right?
Yes, MIPS addi / addiu use a 16-bit signed 2's complement immediate as the low 16 bits of the instruction word. The CPU will sign-extend it to 32 (or 64) bits when decoding.
But note that ori / xori / andi logical instruction use unsigned 16-bit immediates that are zero-extended to 32-bit (or 64-bit), so -1000 is not encodable.
To implement xori $t0, $t1, -1000, you'd need to create a 32-bit -1000 in a register with something like addiu $at, $zero, -1000, then you could xori $t0, $t1, $at. ($at is the "assembler temporary" register that pseudo-instructions like bgt use.)

Does performing unsigned operations on registers cause them to change their sign extension?

For example:
$t1 = 1000 0000 0000 0000 0000 0000 0000 0111
subu $t1, $t1, $zero
Would the register value in $t1 change?
No, it would not.
SUBU works just like SUB except that it doesn't trap on overflow.
From MIPS32™ Architecture For Programmers
Volume II: The MIPS32™ Instruction Set:
The term “unsigned” in the instruction name is a misnomer; this operation is 32-bit modulo arithmetic that does not
trap on overflow. It is appropriate for unsigned arithmetic, such as address arithmetic, or integer arithmetic environments
that ignore overflow, such as C language arithmetic.
The same applies to ADDU and ADDIU.

Exam - Machine code codification

I found this exam question that I have to tell how the beq instruction is coded in machine code.
This is the code:
loop: addu $8, $9, $10
addiu $8, $8, 0x00FF7A01
beq $8, $0, loop
Although my first question would be 0x1100FFFD the correct answer is 0x1100FFFB.
I believe that this is because 0x00FF7A01 is bigger than 16 bit and addiu $8, $8, 0x00FF7A01 must be "decompiled" in more than one instruction.
So here are my questions.
Q1 - In what is addiu $8, $8, 0x00FF7A01 decomplided?
Q2 - And what if the immediate field on the beq instruction was bigger than 16 bits? Must I have to use jumps?
Q1)
For your first question, you mean assemble, not decompiled.
addiu $8, $8, 0x00FF7A01
Your assessment was correct, since the immediate value was bigger than what we can store in a single instruction, we would need to use multiple instructions. The assembler will use the $at (Assembler Temporary, which is $1) register for that.
lui $at, 0x00FF
ori $at, $at, 0x7A01
addu $t0, $t0, $at
Q2)
The branch instructions use what is called PC-relative addressing - the immediate value does not contain the actual address by rather the word offset. Since we know the instruction must be word (2^2) aligned, the low 2 bits are always zero. The actual address will be calculated on the fly by shifting the offset left by 2 and adding it to the address of the instruction following the branch. The final value will be our PC-relative effective address. So we actually have 17 bits to play with (technically 18, but the offset is signed).
When the offset exceeds that range, the assembler will use far branches - a branch followed by a jump.
beq $x, $y, label
will become
beq $x, $y, temp
# ...
j tskip
temp:
j tlabel
# ...
# ...
tskip:
Not sure how the assembler works here, but to allow addiu $8, $8, 0x00FF7A01 be assembled correctly, multiple instructions are necessary, as you have expected. Normally, addiu is a valid instruction that takes in 16-bit integer only.
The instruction addiu $8, $8, 0x00FF7A01 is minimally rewritten as these 3 instructions:
addiu $8, $8, 0x7A01
lui $11, 0x00FF // Assume nothing significant is stored in $11
addiu $8, $8, $11
Since there is now difference of 5 instructions from branch instruction, we need to put -5 in the immediate field of beq, which is 0xFFFB (detailed explanation here).
If the destination is outside the range of -217 to 217-1 bytes (or to the power of 15 in term of number of instructions), then jump instruction must be used.

Finding offset from a code snippet

I am a bit stuck up with the following question,
Consider the following MIPS code and answer the questions that follow.
addi $t1, $s0, 400
loop: lw $s1, 0($s0)
add $s2, $s2, $s1
lw $s1, 4($s0)
add $s2, $s2, $s1
addi $s0, $s0, 8
bne $t1, $s0, loop
What value is the label loop translated to in the conditional branch
instruction?
Now I know the mathematical formula for Branch Target Address. But here as memory addressing is not done so I found out the offset by counting the lines between the target address and PC. This gives the answer to be 7 (word offset). Am I right with this approach?
A quick experiment with MARS simulator http://courses.missouristate.edu/KenVollmar/MARS/download.htm gave me the answer-6, -5 for number of lines difference and another -1 because PC is increased by 1 after the instruction.
AFAIK, I'm afraid not.
As MIPS instruction reference says:
An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
is added to the address of the instruction following the branch (not
the branch itself), in the branch delay slot, to form a PC-relative
effective target address.
So as I understand, the distance from the branch instruction to the loop label is negative (because the label is before the branch, thus the address is lower). The distance is calculated in number of words (hence the 2 bits left shift). As all MIPS instructions are 4 bytes, this would be 6 instructions before, hence -6 is the value that should appear in the branch instruction offset (lower half-word). In binary: 1111 1111 1111 1010 (two's complement). In hexadecimal: FFFA.
Checked with simulator and seems that my reasoning is correct since the instruction is coded as 0x1530FFFA.

Showing a BEQ MIPS instruction in binary

beq $s1, $s2, endif(assume endif is 22 instructions after the branch)
The answer to the following question is
000100 10001 10010 0000000000001111
Can someone explain what "assume endif is 22 instructions after the branch" means?
Helpful data:
opcode for beq is 000100
$s1 is 10010
$s2 is 10001
I just need help understanding how we get the last part, which is the endif.
You want to jump to the 22th instruction after the beq, that is skip the next 21 instructions.
Now, that would be 10101 binary which is 21 decimal (the number of instructions to skip).
The instruction for such a jump would be 0001 0010 0011 0010 0000 0000 0001 0101 and not what you have written (your branch offset is wrong).
You have to take into account that in MIPS every instruction is the same size (4 bytes), thus the branches count the number of words (4 bytes each) to jump.
As a note aside, these values are encoded in two's complement so when you skip forward you just have to read that number in binary and if it were backwards you would have to apply two's complement to "see" were it will jump.