说我有以下汇编代码:
subroutineA:
....some assembly code....
subroutineB:
....some assembly code....
subroutineC:
....some assembly code....
现在,在另一个子例程中,我想构建一些随机分支到上面3个子例程之一的东西。
类似的东西:
subroutineD:
....some code to randomly branch to either
subroutineA, or subroutineB, or subroutineC ....
如何在ARM汇编程序中有效地执行此操作?
以下是我最终解决问题的方法,并且有一天它可能对其他人有帮助(下面的伪代码):
我在Assembly中声明了一个数组来存储所有子程序标签(它们的内存地址):
.global my_arr
my_arr:
.long subroutineA
.long subroutineB
.long subroutineC
.......
我在Assembly(LFSR)中也有一些随机数生成器。假设我在R0
中有随机数(当然,确保0和子程序总数之间的随机数),那么我会做类似的事情:
ldr R4, =my_arr
ldr R5, [R4, R0]
然后在R5
中,我有随机子程序的地址。然后我可以简单地做:
blr R5
转到子程序。
答案 0 :(得分:1)
您可以有效地实现这样的跳转表,
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第二版 9.2.5 Multi-Way branch 中实现switch类型语句的好方法,
cmp r0,#max
addlo pc, pc, r0, LSL #routineSizeLog2
b outOfRange
index0:
...
index1:
...
index2:
...
编译器通常会执行我的第一个版本(函数指针类型),但不需要保存lr
来实现切换。通常case
语句不是那么线性。但是,许多人使用David Seal的方法在汇编程序中创建中断处理程序等。