#38303 - sajiimori - Fri Mar 25, 2005 5:44 pm
Here's some functionality I implemented for ARM. I'd like to do the same thing on x86 but I don't really know that architecture very well.
The routine above swaps out sets of registers, excluding the ones that don't need to be saved between function calls (r0-r3, r12).
Swapping again with the old set should resume execution just after the first exchange was performed.
Just before the new registers are loaded, the register used for return values (r0 or eax) must contain "result".
Code: |
struct SavedRegs { int r4, r5, r6, r7, r8, r9, r10, r11, r13, r14, r15; }; asm int exchange( int result, // r0 SavedRegs* oldState, // r1 SavedRegs* newState) // r2 { stmea r1, {r4-r11, r13-r14} // Store regs into oldState, except pc. add r3, pc, #4 // Store pc seperately, because it must // be modified to point at bx lr. str r3, [r1, #40] // pc is 40 bytes from start of struct. ldmfd r2, {r4-r11, r13-r15} // Restore from newState bx lr // Later, exchanging for oldState puts // us back here. } |
The routine above swaps out sets of registers, excluding the ones that don't need to be saved between function calls (r0-r3, r12).
Swapping again with the old set should resume execution just after the first exchange was performed.
Just before the new registers are loaded, the register used for return values (r0 or eax) must contain "result".