Tutorial By: Creator
Skill Level Needed: 2.0 out of 5.0
This is what I've Learned in MIPS So far.
Warning: This Guide Will Probably Be hard for beginning Coders
So Read as Much as you can and I hope it helps.
-----------------------------------Code:The PSP has a MIPS CPU with 32 registers of 32 bits. Processor Registers: ;I Learned This When I First Started Codeing it's easy and Fun to learn Name: | Register: | Function: $at 1 Reserved for the operating system $v0 2 Passes values to and from functions $v1 3 Passes values to and from functions $a0 4 Passes the first of four arguments $a1 5 Passes the second of four arguments $a2 6 Passes the third of four arguments $a3 7 Passes the fourth of four arguments $t0 8 Holds temporary variables $t1 9 Holds temporary variables $t2 10 Holds temporary variables $t3 11 Holds temporary variables $t4 12 Holds temporary variables $t5 13 Holds temporary variables $t6 14 Holds temporary variables $t7 15 Holds temporary variables $s0 16 Callee-saved registers $s1 17 Callee-saved registers $s2 18 Callee-saved registers $s3 19 Callee-saved registers $s4 20 Callee-saved registers $s5 21 Callee-saved registers $s6 22 Callee-saved registers $s7 23 Callee-saved registers $t8 24 Holds temporary variables $t9 25 Holds temporary variables $k0 26 Reserved for the operating system $k1 27 Reserved for the operating system $gp 28 Global memory pointer $sp 29 Stack pointer to the first free location $fp 30 Frame pointer $ra 31 Return address
---------------------------------Code:Basic MIPS instructions: ;I'm Still Learning Some of these Call: | Argument 1: | Argument 2: | Argument 3: | Description: add rd rs rt rd = rs + rt (with overflow) addu rd rs rt rd = rs + rt (without overflow) addi rt rs Imm rt = rs + imm (with overflow) beq rs rt label Branch to label if (rs==rt) j label Jump to label jal label Jump to label and save next instruction address in $ra jr rs Number jump to instruction at (rs) lui rt Address upper halfword of rt = 16-bit number lw rd Offset(base) load the word at address into rd lw rd Load word at addr offset+base into rd nop No operation or rd rs rt rd = rs OR rt ori rt rs Imm rt = rs OR imm sw rt Address store the word in rt to address sw rt Offset(base) store word in rt to addr offset+base Syscall Do a system call depending on contents of $v0 xor rd rs rt rd = rs XOR rt
Loading a 32 bit constant: MIPS has only 16 bits of immediate value:
Another particular design feature is that immediate instructions only have 16 bits of immediate value. It is not an issue if the immediate
value is small, but when we want to load a 32 bit word into a register, we need to do it in a two step process: first load the most
significant 16 bits using “lui” (load upper immediate) and or the result with the lowest 16:
----------------------------------Code:lui $a0, 0xdead ori $a0, $a0, 0xbeef
Differences between J and JAL
;Im not really sure who made these but I did not i talk no credit.
In MIPS the j-type instructions are j (opcode 000010) and jal (opcode 000011). The instructions require a 26-bit field to specify the
target of the jump. In both cases, the coded address is formed from the bits at positions 27 to 2, and bits 1 and 0 are zero since the
instructions are 32-bit aligned (e.g. you can't do JAL 0x03). The full 32-bit jump target address is formed by concatenating the high
order 4 bits of the program counter (PC, the address of the instruction following the jump) 26 bits of the target and two 0 bits. For
simplicity, just consider that the coded address in the j-type instruction is 26 bits getting the wanted memory address divided by 4.
Both J-type instructions perform a direct call: J means "jump to" and JAL means “Jump and Link”, to be read as "jump to and set the
register $ra to the return address where we are supposed to come back"., so the when the PSP executes a jump it does not forget
where it was. In other words, the JAL instruction corresponds to a "call" setting the $ra register to the address of the instruction right
after the JAL (+4). The called method must then store the $ra register in the stack before calling another method and restoring it to the
good value when done so the return address is not clobbered.
The address field of a conditional branch contains a 16 bit two's complement
[(adress of target) - (address of branch) - 4 ] / 4
In order to better understand the differences, consider this pseudo-code snippet:
A simplified equivalent assembly code would look like this:Code:void bar () { ... } void foo () { bar (); } int main () { foo (); }
At this moment, the register $ra points at the address 0x1000000C (we do not consider the one-slot delay instruction here)Code:main: 0x10000004 jal foo 0x10000008 nop 0x1000000C ... 0x10000010 ...
foo:
[code]0x20000000 addiu $sp, $sp, -4 ;reserve 4 bytes in the stack
0x20000004 sw $ra, 0($sp) ;store the ra in the stack
0x20000008 jal bar ;call bar with $ra = 0x2000000C
0x2000000C nop
0x20000010 lw $ra, 0($sp)
0x20000014 jr $ra ;restore sp, jump to return address
0x20000018 addiu $sp, $sp, 4
When the instruction jal bar is executed, the register $ra points at 0x20000010
bar:
When the bar function ends, the control is transferred to address 0x200000010, then foo finishes and returns to mainCode:0x30000000 addiu $sp, $sp, -4 ;reserve 4 bytes in the stack 0x30000004 sw $ra, 0($sp) ;store the ra in the stack --- lw $ra, 0($sp) jr $ra ;restore the sp and jump to return address addiu $sp, $sp, 4
(0x1000000C).
So, if we replaced the "jal bar" by "j bar" what would happen? Since the $ra is not set, it still points to 0x1000000C. The bar function
would indeed save the value in stack and set it back when done.... to 0x1000000C. Indeed, the jr $ra at the end off bar would return
control....to main! (Leaving foo unfinished, plus side effects such as stack leaks and sp shifts).... bad things would happen.
---------------
End.
Please Rate and Comment on this Tutorial
Enjoy Coding. -Creator