@ ---------------------------------------------------------------------- @ second attempt (first: s/lr/r11/, otherwise identical) @ pro: leaves all unnecessary registers undisturbed @ con: have to branch to a branch to restart _start: ldr IP, =THREAD ldr FS, =STACK dothread: ldm IP!, {lr} blx lr b dothread .macro next bx lr .endm @ ---------------------------------------------------------------------- @ third attempt @ pro: 'bx lr' branches are now straight to dothread, instead of to @ a branch to it @ con: r10 has been reduced from a general register to a scratch @ register whose value is lost between IP movements @ also lr must be set on each iteration to the same thing... _start: ldr IP, =THREAD ldr FS, =STACK dothread: ldm IP!, {r10} ldr lr, =dothread bx r10 .macro next bx lr .endm @ ---------------------------------------------------------------------- @ fourth attempt @ pro: incorporates all previous 'pro' statements @ con: ... are there any? @ words must preserve lr, but that was always the case _start: ldr IP, =THREAD ldr FS, =STACK ldr lr, =dothread dothread: ldm IP!, {PC} .macro next bx lr .endm @ ---------------------------------------------------------------------- @ fifth attempt @ pro: not even lr is reserved. there are no branches back to this point @ con: perhaps there are limitations with ldm'ing to PC? .macro next ldm IP!, {PC} .endm _start: ldr IP, =THREAD ldr FS, =STACK next