Question about bla opcode

Started by biolizard89, September 02, 2010, 09:52:40 AM

Previous topic - Next topic

biolizard89

So I'm trying to make a C0 code that branches to a location in the code handler (it's one of the USB Gecko routines, in case anyone's curious).  I found the routine, but when I try to assemble the instruction with PyiiASMH:

bla 0x80001E34

I get the following error:

./tmp/code.txt: Assembler messages:
./tmp/code.txt:15: Error: operand out of range (0x80001e34 is not between 0xfe000000 and 0x01fffffc)

I gather that the instruction doesn't like addresses in the 0x80xxxxxx range.  The following does assemble:

bla 0x00001E34

But how exactly does the Wii know to use the 0x80xxxxxx range (and not, say, somewhere in MEM2) if I don't specify it in the instruction?  Is there something I need to do to make sure that it goes to the correct address (0x80001E34)?

I'm fairly inexperienced with ASM, so any explanation would be appreciated.

Thanks!

Romaap

If I remember correctly, the Wii can't branch to an actual address with the normal branch.
This is because the ASM instructions are all 32bits, and since the address itself is also 32bits the instruction cant hold the address completely.

The branch instruction will branch to the Program Counter + the value you specify.
The error message says the value can be between -0x2000000 and 0x1FFFFFF

In order to do an absolute branch you will need to load the address in a free register, move that into the ctr and use bctr.

example:
I want to branch to 0x12345678

lis   r12,0x1234
ori   r12,r12,5678
mtctr   r12
bctr

dcx2

Romaap is mostly right...when the absolute bit is 1, the address of the instruction is not used to compute the branch destination, so bla is what you wanted to use.  But he is correct that the absolute branches in the Wii are pretty useless because they can't reach our codes.

Take a look at the datasheet for the branch instruction.  Specifically, note the last two bits.  b30 is the absolute bit, and b31 is the link bit.  Any branch can be made to be absolute or link by setting these bits.

http://pds.twi.tudelft.nl/vakken/in1200/labcourse/instruction-set/b.html

Further, look at the LI field.  It is 24 bits long.  (With conditional branches, you only get like 14 bits!)  This explains the limitation in branch destinations...there's no way to give it the upper 8 bits of address (same problem we have with code types like 04, that is solved with things like ba/po)

Romaap is also right about how to do it; load r12 with your absolute address, mtctr r12, but then you want to bctrl.  This way the destination routine will get the right LR.

Deathwolf

but what's the different between "load into address" and "branch to address"?
lolz

dcx2

Not sure I understand your question...

Normally, branches are relative to the current instruction.  So you can go 0x1FFF bytes forward or backward.  The destination must be close to where you are right now.  This is how it "skips instructions"

lis/ori/mtctr/bctrl is how to branch to a specific 32-bit address to branch destination.

Deathwolf

#5
is it possible to write anything with it, like load into address?
you said it skip the instrucion, if not equal-equal etc. but what does only b do?
as you said "you can go forward or backward".

do you mean something like this?
hook address 80346845.

b 0x1234
lis r12,0xFFFF
ori r12,r12,FFFF

branch 1234 bytes forward.
in disassembler b 0x80347A79
lolz

dcx2

beq/bne/blt are conditional branches.  They branch or not branch depending on the Condition Register.

b will always branch, regardless of any condition.

Deathwolf

you mean IF branches. (beq/bne/blt)
is it right? always branch 1234 bytes forward.

hook address 80346845.

b 0x1234
lis r12,0xFFFF
ori r12,r12,FFFF

branch 1234 bytes forward.
in disassembler b 0x80347A79
lolz

biolizard89

Thanks Romaap and dcx2, your suggestions were very helpful.  I now have it working.  :)