在 ARM 程序集中分支到不同的子程序? [英] Branching to different subroutines in ARM assembly?
问题描述
假设我有以下汇编代码:
Say I have the following assembly code:
subroutineA:
....some assembly code....
subroutineB:
....some assembly code....
subroutineC:
....some assembly code....
现在,在另一个子程序中,我想构建一些将随机分支到上述 3 个子程序之一的东西.
Now, in another subroutine, I want to build something that will randomly branch to one of the 3 subroutines above.
类似于:
subroutineD:
....some code to randomly branch to either
subroutineA, or subroutineB, or subroutineC ....
如何在 ARM 汇编程序中有效地做到这一点?
How can do this efficiently in ARM assembler?
这是我最终解决问题的方式,它可能有一天会帮助其他人(下面的伪代码):
Here is how I ended up solving the issue and it might help someone else some day (pseudo code below):
我在Assembly中声明了一个数组来存储所有的子程序标签(它们的内存地址):
I declared an array in Assembly to store all the subroutine label (their memory address):
.global my_arr
my_arr:
.long subroutineA
.long subroutineB
.long subroutineC
.......
我在程序集 (LFSR) 中也有一些随机数生成器.假设我在 R0
中有随机数(当然,确保 0 和子程序总数之间的随机数),然后我会做这样的事情:
I also have some random number generator in Assembly (LFSR). Say I have have the random number in R0
(of course, make sure random number between 0 and total number of subroutine), then I would do something like:
ldr R4, =my_arr
ldr R5, [R4, R0]
然后在R5
,我有随机子程序的地址.然后我可以简单地做:
And then in R5
, I have address of random subroutine. And then I can simply do:
blr R5
进入子程序.
推荐答案
你可以有效地实现这样的跳转表,
You may efficiently implement a jump table like this,
adr lr, return
cmp r0, #3
ldrlo pc, [pc, r0, lsl #2] @ pc is 8 bytes ahead
b error @ also functions as padding
.long subroutineA
.long subroutineB
.long subroutineC
return:
@ one of three routines finished here.
...
error:
@ random out of array range.
这是非常通用的.David Seal 在 ARM ARM 2nd edition 的 9.2.5 Multi-Way branch 中提供了一种实现 switch 类型语句的好方法,
This is very generic. David Seal gives a nice way to implement a switch type statement in 9.2.5 Multi-Way branch of the ARM ARM 2nd edition,
cmp r0,#max
addlo pc, pc, r0, LSL #routineSizeLog2
b outOfRange
index0:
...
index1:
...
index2:
...
编译器通常做我的第一个版本(函数指针类型),但不需要保存lr
来实现切换.通常 case
语句不是那么线性的.但是,许多人使用 David Seal 的方法在汇编程序中创建中断处理程序等.
Compilers usually do my first version (function pointer type), but do not need to save lr
to implement a switch. Usually case
statements are not so linear. However, many people create interrupt handlers, etc in assembler using David Seal's method.
这篇关于在 ARM 程序集中分支到不同的子程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!