jiangzhengwenjzw
now working on katam
- 181
- Posts
- 12
- Years
- Seen yesterday
I see now. You're confused as to why we can use r2 as the bx register for our jump when it's not safe to use in general. Allow me to explain.
Lets first take a look at the routine at 0809A8BC.
Spoiler:
Code:ROM:0809A8BC @ =============== S U B R O U T I N E ======================================= ROM:0809A8BC ROM:0809A8BC ROM:0809A8BC item_by_id: ROM:0809A8BC ROM:0809A8BC PUSH {LR} ROM:0809A8BE LSL R0, R0, #0x10 ROM:0809A8C0 LSR R0, R0, #0x10 ROM:0809A8C2 BL itemid_sanitize ROM:0809A8C6 LSL R0, R0, #0x10 ROM:0809A8C8 LSR R0, R0, #0x10 ROM:0809A8CA MOV R1, #sizeof(item) ROM:0809A8CC MUL R0, R1 ROM:0809A8CE LDR R1, =item_undefined ROM:0809A8D0 ADD R0, R0, R1 ROM:0809A8D2 POP {R1} ... ... ROM:0809A8A4 itemid_sanitize: @ CODE XREF: item_by_id+6p ROM:0809A8A4 ROM:0809A8A4 PUSH {LR} ROM:0809A8A6 LSL R0, R0, #0x10 ROM:0809A8A8 LSR R1, R0, #0x10 ROM:0809A8AA MOV R0, #0x176 ROM:0809A8AE CMP R1, R0 ROM:0809A8B0 BHI loc_809A8B6 ROM:0809A8B2 MOV R0, R1 ROM:0809A8B4 B loc_809A8B8 ROM:0809A8B6 @ --------------------------------------------------------------------------- ROM:0809A8B6 ROM:0809A8B6 loc_809A8B6: ROM:0809A8B6 MOV R0, #0 ROM:0809A8B8 ROM:0809A8B8 loc_809A8B8: ROM:0809A8B8 POP {R1} ROM:0809A8BA BX R1 ROM:0809A8BA @ End of function itemid_sanitize ROM:0809A8BA ROM:0809A8BC
As you can see, the whole function doesn't use r2. However, this is just something that happened in this specific case. We can tell by just looking at the above routines that this function doesn't use r2 as a parameter AND that r2 isn't used for any of the calculations. However, there can be routines which don't take r2 as a parameter but use it for calculation inside the routine.
In general, if the registers aren't specifically used as parameters, you can use them to call the function. If they're not parameters, the only way for them to be used inside the routine is for calculations. For example, lets look at the other routine you were talking about.
Code:ROM:08008DA4 gf_strcat: ROM:08008DA4 ROM:08008DA4 PUSH {LR} ROM:08008DA6 MOV R2, R0 ROM:08008DA8 B loc_8008DAC ROM:08008DAA @ --------------------------------------------------------------------------- ROM:08008DAA ROM:08008DAA loc_8008DAA: ROM:08008DAA ADD R2, #1 ROM:08008DAC ROM:08008DAC loc_8008DAC: ROM:08008DAC LDRB R0, [R2] ROM:08008DAE CMP R0, #0xFF ROM:08008DB0 BNE loc_8008DAA ROM:08008DB2 MOV R0, R2 @ dst ROM:08008DB4 BL strcpy_xFF_terminated ROM:08008DB8 POP {R1} ROM:08008DBA BX R1
Clearly here, r2 cannot be a Parameter because it's overwritten by r0 in the first OP code after the push statement. In fact, if r2 or r1 isn't a parameter, but it used in calculations, the routine must first make measures to "clean" or set them. This is because the function doesn't know from where it may be getting called from. In this case r2 is overwritten with r0, so the old value of r2 is irrelevant to the function. Notice that because r2 is overwritten, the function which calls this one had it's old value of r2 changed. This is what I mean by "we cannot guarantee registers r0-r3 aren't overwritten".
To take away from this, basically if a register isn't used specifically as a parameter for the function, and is a low register, then it's safe to use as a caller register.
I got what you meant in the above reply now, but I think there's still a specific case which cause problem. (Not the case in the tutorial as the tutorial do not cause such problem) To show it more clearly, I will make an example:
Firstly, the routine at 0809A8BC was called (which is already modified) so that r2 was changed.
Then an unknown routine is called, which use R2 as a parameter.
For pseudo code:
.......(instructions, which turns r2 into 0x1 for example)
bl 0809A8BC(r2 is changed into a pointer as the routine is modified)
bl 08XXXXXX(take r2 as a parameter to output something)
.......(Not related codes)
As you can see, I think it may cause problem... I think what you said is the case when the function at 08XXXXXX doesn't take r2 as a parameter, as in the tutorial. Or did I ignore something in your words? Thank you very much.