2014-09-29 56 views
-3

说我有以下汇编代码:在ARM程序集中分支到不同的子例程?

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汇编程序有效地做到这一点?

这里是我结束了解决这个问题,它可能会帮助别人的某一天(伪下面的代码):

我宣布大会阵列来存储所有的子程序标签(它们的内存地址):

.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

@OliverCharlesworth我猜你在暗示什么,先是生成一个数字,然后做一个比较,如果number是1,那么执行bl subroutineA,如果number是2,执行bl subroutineB,依此类推。但是如果我有很多子程序,这会变得非常低效吗?也许我不明白你在说什么? – JJackJi 2014-09-29 23:00:18

+0

@GregHewgill我是新来的大会,我只是想了解什么是最好的方式去做这样的事情。用C语言(或其他语言)说,我会将所有子例程存储在某个结构中,并生成一个随机数,然后跳转到结构中该索引处的子例程。 – JJackJi 2014-09-29 23:01:56

+1

你可以在汇编语言中做几乎完全相同的事情。创建一个函数地址数组,并根据随机数对数组中的某个函数进行间接调用。 – 2014-09-29 23:21:43

回答

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. 

这是非常通用的。大卫密封给出了一个很好的方式来实现在9.2.5多路分支的ARM ARM第二版开关类型语句,

cmp r0,#max 
addlo pc, pc, r0, LSL #routineSizeLog2 
b  outOfRange 
index0: 
... 
index1: 
... 
index2: 
... 

编译器通常做我的第一个版本(函数指针类型),但这样做不需要保存lr来实现交换机。通常case报表不是线性的。但是,许多人使用David Seal的方法在汇编程序中创建中断处理程序等。

+0

那么,这不是编译器实现开关的唯一方式,但它是一种常见的方式。 – 2014-10-09 19:13:45

相关问题