calculate target address for mips jalr - mips

I have the following assembly code disassembled using capstone. I started with entry point obtained from header.
.text : 4195648
...
...
0x400584L lui $t9, 0x40
0x400588L addiu $t9, $t9, 0xba0
0x40058cL jalr $t9
How do I find which address jalr is pointing to? (I thought I could reach main function in C program)
Based on slide number 19 in this reference I made target = 0x0400ba0
I looked for it and found it in .plt section. Here is the disassembly of .plt
.plt : 4197152
...
...
0x400ba0L lui $t7, 0x41
0x400ba4L lw $t9, 0xbe4($t7)
0x400ba8L jr $t9
0x400bacL addiu $t8, $t7, 0xbe4
I am confused - How do I make sense of it. Or how can I reach actual main function in the MIPS disassembly

Related

How to return to a specific point in a MIPS program

I am writing a function in MIPS that will divide two fractions stored in the a0-a3 registers, like so: (a0/a1) and (a2/a3). I already have a function that will multiply both fractions together, so all I need to do is switch the numerator and denominator on the second fraction and call my multiplication function. I have that part figured out, however I also need to make sure that the numerator retains the sign, meaning that if I flip the second fraction around, and it's a negative, then I need to multiply both the numerator and the denominator by -1. I have written a separate function to do this for me, but after calling that function I don't know how to jump back to where I was. Here is the code:
f_div:
#Flip the second fraction (a2/a3) -> (a3/a2)
add $t0, $a2, $0
add $a2, $a3, $0
add $a3, $t0, $0
ble $a3, $0, f_flipsign #Branch if $a3 <= 0
#I need to be able to jump back here from f_flipsign
#How do I arbitrarily jump back to a location in the program without
#direct access to the PC?
add $s0, $ra, $0 #Save $ra so I don't lose it when I jal f_mul
jal f_mul
add $ra, $s0, $0 #Put the original $ra back
# Also, is there a better way to do this ^
jr $ra #Jump back to main
f_flipsign:
li $t0, -1
mult $a2, $t0
mflo $a2
mult $a3, $t0
mflo $a2
jr ? #How do I make this jump back to the middle of f_div?
I have researched and studied for hours today and I can't seem to figure this out. I understand how these instructions are formatted, I just need to know how to accomplish this one thing. Any help is greatly appreciated, thank you for taking your time.
If your f_flipsign subroutine is in fact some code you just need to execute only in that case, then maybe it does not have to be a subroutine at all and just change the branch condition and add the flip sign code there.
In that case, just change the ble to a bgt to skip the flip code, e.g.:
bgt $a3, $0, dont_flip #Branch if $a3 > 0
# Your code to flip sign
li $t0, -1
mult $a2, $t0
mflo $a2
mult $a3, $t0
mflo $a2
dont_flip:
# Code continues here (whether it flipped sign or not)
If flip_sign is a subroutine that may be called from many places, then you should use jal-code-jr, but you have to preserve $ra somewhere (usually the stack) so that it is not lost when calling the subroutine.
Assuming you have preserved $ra, then you would write something like this:
bgt $a3, $0, continue #Branch if $a3 > 0
jal f_flipsign
continue:
# Code continues here (whether it flipped sign or not)
and in your f_flipsign subroutine end with:
jr $ra

MIPS: Code Scheduling To remove Stalls

I have the following MIPS code:
addi $s1, $0, 10
lw $t0, 4($s0)
srl $t1, $t0, 1 [STALL becausee $t0 depends on lw's $t0]
add $t2, $t1, $s1 [STALL because $t1 depends on srl's $t1]
sw $t2, 4($s0)
How can I rearrange it to avoid any stalls. I see that all the 2 to 5 line's sequence can't change. We can only move the first line in between srl and add OR lw and srl. Any ideas?
There are 4 read after write (RAW) dependencies in your code: addi->add, lw->srl, srl->add, add->sw. These can't be fixed as you pointed out.
What you can do is move the addi instruction. I would think the best place to move this instruction would be after the lw because in the MIPS architecture all load instructions use a load delay slot. This means that the instruction immediately after the load does not have access to the contents of the load. If you are using this code in a simulator such as spim or MARS this may not be simulated, but assuming you mean to use the loaded value of $t0 in the srl instruction, your assembly above is actually incorrect. For this to work, there should be a nop in between the lw and srl.
For that reason, it would be best to move the addi in between the lw and srl so as to utilize the lw load delay slot.

Using lw on address of $ra

Assuming we have something of this sort in MIPS
jal F
F: lw $t1, 0($ra)
lw $t2, 8($ra)
What would we have in $t1 and $t2?
Will $t1 have the instruction code of F??
Say X is the address of label F
when jal is called $ra will hold X
you load what is on $ra to $t1 which is the binary machine laguage of the instruction at X
then you load what is 2 words lower (8) which is here not specified in your code, you need to show a 4th line of code to tell you =)

Can I use $PC in MIPS

As far as I know, program counter, $PC is hidden from users. It isn't one of the 32 registers.
I want to do the following, instead of using jal
$ra <= PC + 4
j my_function
# instead of jal my_function
Is is possible to do this? I know JAIL is a macro.
How can I jump to a function without using JAL and able to return to the next instruction of the caller? Thanks.
Thanks!
One supported method of "discovering" the PC in code is to use JAL
with a zero offset (to jump/link to the next instruction), then read
the PC out of R31.
Attempt:
..statements before jump...
jal $0
addi $t3, $ra, 4
..statements when function returns..
I end up in infinite loop.
Doing a JAL to find out the PC is quite useless since you can use that JAL to do the jump... One way to do it is using LA pseudo-instruction, something like:
la $ra, current
addiu $ra, $ra, 8
current:
j example
nop
return:
j return
nop
example:
jr $ra
nop

the functions (procedures) in MIPS

I'm new in MIPS language and I don't understand how the functions (procedures) in the MIPS assembly language work. Here are but I will specify my problem :
What does:
jal
jr
$ra
mean in mips language and the important thing
How can we use them when we want to create a function or (procedure)?
Firstly, you might want to check this quick MIPS reference. It really helped me.
Secondly, to explain jal, jr and $ra. What jal <label> does is jump to the label label and store the program counter (think of it as the address of the current instruction) in the $ra register. Now, when you want to return from label to where you initially were, you just use jr $ra.
Here's an example:
.text
main:
li $t0, 1
jal procedure # call procedure
li $v0, 10
syscall
procedure:
li $t0, 3
jr $ra # return
You will notice when running this in a SPIM emulator that the value left in $t0 is 3, the one loaded in the so-called procedure.
Hope this helps.
1.the first two are instructions,the third it's kind of special register
jal=jump and link (Address of following instruction put in $ra,and jump to target address)
jr=jump to specify register
$ra=return address
we often use the instruction like this ...
jr $ra (Copy $ra to program counter)
it means return(jump) to the address saved in $ra .
2.
Here's an example function (procedure) in C
int main(){
x=addthem(a,b);
}
int addthem(int a, int b){
return a+b;
}
function in MIPS
.text
main: #assume value a is already in $t0, b in $t1
add $a0,$0,$t0 # it's the same function as move the value
add $a1,$0,$t1
jal addthem # call procedure
add $t3,$0,$v0 # move the return value from $v0 to where we want
syscall
addthem:
addi $sp,$sp,-4 # Moving Stack pointer
sw $t0, 0($sp) # Store previous value
add $t0,$a0,$a1 # Procedure Body
add $v0,$0,$t0 # Result
lw $t0, 0($sp) # Load previous value
addi $sp,$sp,4 # Moving Stack pointer
jr $ra # return (Copy $ra to PC)
You will want to read the System V Application Binary Interface, MIPS RISC Processor Supplement. This describes the conventions used for calling functions, in particular how the stack is managed and parameters are exchanged (there is no hardware stack in MIPS, everything is a matter of software conventions, and the ABI defines those conventions).
The document above assumes some basic knowledge of what MIPS instructions do, so you will also need the MIPS32 Architecture for Programmers, in particular volume II (instruction set), which describes the detailed effect of each instruction. But, do yourself a favor, download and read volume I (introduction) first.
The jal instruction is the "jump and link" opcode. It jumps at the target address (which is the address of the first opcode of the called procedure) while saving the current instruction pointer into the link register, which is register 31 (to be precise, it saves in register 31 the value x+8, where x is the address of the jal opcode itself).
jal: aka jump and link against any function name will redirect you to the required function.
jr $ra: It returns the value from a function that was called.
main function:
.data
x: .word 3 # initializing x to be 3
y: .word 5 # initializing y to be 5
answer: .word 0 # intialzing answer to be 0
prompt: .asciiz "Add X to Y: " # console prompt for final answer
.text
.globl main
.ent main
main:
lw $a0, x # pass arguments to function $a0 - x, $a1 - y
lw $a1, y
jal adds # adds function is called
sw $v0, answer # answer from the returned value
la $a0, prompt # displaying prompt on the console
li $v0, 4
syscall
lw $a0, answer # displaying final answer on the console
li $v0, 1
syscall
li $v0, 10 # end program
syscall
.end main
adds function:
.globl adds
.ent adds
adds: # adds function
li $v0, 0
add $v0, $a0, $a1 # adding arguments to the callee
jr $ra # return
.end adds