在 ARM 程序集中分支到不同的子程序? [英] Branching to different subroutines in ARM assembly?

查看:17
本文介绍了在 ARM 程序集中分支到不同的子程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下汇编代码:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆