I just want to check my understanding of these two concepts is correct, as I have been trying to finish a project and while everything works to my expectations, it keeps narrowly failing the test cases and introducing a random value...
Basically, the objective of the project is to write out a branch instruction to console in this form:
BranchName $S, [$t, if applicable] 0xAbsoluteAddressOfBranchTargetInstruction
Edit: Clarification: I'm writing this in MIPS. The idea is I get a memory address in $a0 given to the program by my instructor's code (I write the function). The address is for the word containing a MIPS instruction. I'm to do the following:
- Get instruction
- Isolate instruction opcode and output its name to register (ie: opcode 5, output BNE), do nothing if it isn't a branch instruction.
- Isolate $s, $t, and output as applicable (ie: no $t for bgez)
- Use offset in the branch instruction to calculate its absolute address (the address of the target instruction following branch) and output in hex. For the purposes of this calculation, the address of the branch instruction ($a0) is assumed to be $pc.
IE:
BEQ $6, $9, 0x00100008
Firstly, is my understanding of branch calculation correct?
- PC -> PC + 4
- Lower 16 bits of instruction
- << 2 these lower bits
- Add PC+4 and the left shifted lower 16 bits (only the lower 16 though).
Secondly, could somebody tell me which bits I need to isolate to know what kind of branch I'm dealing with? I think I have them (first 6 for BEQ/BNE, first 16 with $s masked out for others) but I wanted to double check.
Oh, and finally... should I expect deviation on SPIM from running it on an Intel x86 Windows system and an Intel x86 Linux system? I'm getting a stupid glitch and I cannot seem to isolate it from my hand-worked address calculations, but it only shows up when I run the test scripts my prof gave us on Linux (.sh); running directly in spim on either OS seems to work... provided my understanding of how to do the hand calculations (as listed above) is correct.
spim
obeysPC+4
[as doesmars
]. But, mips has [can have] "branch delay slots". Normally, emulation for these is defaulted off forspim/mars
but you may have enabled it somehow (e.g. registry entry, etc.). See my answer: stackoverflow.com/questions/36994841/… If enabled but not compensated by you, you'd experience an "off-by-4" discrepancy – Craig Esteyword_offset = *(short *) ...
. To do it in mips, assuming$t5
has the whole [branch] instruction value, do:sll $t4,$t5,16
--this puts the [16 bit] sign bit into bit 31, followed bysra $t4,$t4,16
[shift right arithmetic which does the sign extension when shifting]. Now,$t4
has the sign extended word offset. To get the byte offset, now dosll $t4,$t4,2
– Craig Estey