【问题标题】:Branching to different subroutines in ARM assembly?分支到 ARM 汇编中的不同子例程?
【发布时间】:2014-09-29 22:38:52
【问题描述】:

假设我有以下汇编代码:

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

进入子程序。

【问题讨论】:

  • @OliverCharlesworth 我猜你的意思是,首先生成一个数字,然后进行比较,如果数字为 1,则执行 bl subroutineA,如果数字为 2,则执行 bl subroutineB,依此类推.但是如果我有很多子程序,这会变得非常低效吗?可能我没听懂你在说什么?
  • 你可以用汇编语言做几乎完全相同的事情。创建一个函数地址数组,并根据随机数间接调用该数组中的一个函数。
  • 跳转表在汇编中可能比在大多数高级语言中更简单。如果这个问题真的是关于“构建某些东西”的“一些代码”的特定实现,它可能应该这么说
  • @JJackJi 第一条规则是更具体 - 您清楚地了解自己的目标,但您向我们提出的想法含糊不清:“如何实施汇编中的 RNG 算法”是一个问题,“如何从汇编代码中调用rand()”是另一个问题,“如何最好地根据变量调度不同的函数调用”是第三个问题。前两个,一旦明确定义,很容易搜索(事实上,一个简单的线性同余生成器在 C 中非常容易,因此可以进行很好的汇编练习)。第三个将保证更多细节,例如所有函数都具有相同的签名吗?
  • @Notlikethat 刚刚更新,现在好点了吗?

标签: assembly arm


【解决方案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 2nd edition 的 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 的方法在汇编程序中创建中断处理程序等。

【讨论】:

  • 嗯,这不是编译器实现开关的唯一方式,但它是一种常见方式。
猜你喜欢
  • 2011-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多