在ARM汇编语言中,子程序调用是通过BL指令来完成的。BL指令的语法格式如下:
BL subname
其中:subname是被调用的子程序的名称。BL指令完成2个操作,即将子程序的返回地址放在LR寄存器中,同时将PC寄存器值设置成目标子程序的第一条指令地址。
在返回调用子程序时,转移链接指令保存到LR寄存器中的值需要拷贝回程序寄存器PC。对于最简单的子程序,一条MOV指令就可完成子程序的返回,例如:
SUB2 …
MOV PC,R14 ;把R14拷贝到R15来返回
其实,任何数据处理指令都可用来计算返回地址,但是MOV指令时至今最常见的形式。碎玉在子程序中出现嵌套调用时,链接寄存器LR中的返回地址可能会在第二次调用时被覆盖,所以需要将返回地址压入堆栈来进行保存。在子程序返回时,返回地址和保存的工作寄存器都可用多寄存器存取指令恢复。例如:
SUB1 STMFD R13!,{R0-R2,R14} ;保存工作寄存器和链接
BL SUB2
…
LDMFD R13!,{R0-R2,PC} ;恢复工作寄存器并返回
需要注意的是,返回地址是直接恢复到程序计数器PC,而不是链接寄存器LR。这种单元恢复和返回指令是非常有用的。
下面是一个子程序调用的简单例子。子程序DOADD完成加法运算,操作数放在R0和R1寄存器中,结果放在R0中。
AREA EXAMPLE,CODE,READONLY
ENTRY
Start MOV R0,#10 ;设置输入参数R0
MOV R1,#3 ;设置输入参数R1
BL Doadd ;调用子程序Doadd
…
Doadd ADD R0,R0,R1 ;子程序
MOV PC,LR ;从子程序中返回
END ;结束汇编
凡《网络安全与数据治理》(原《信息技术与网络安全》)录用的文章,如作者没有关于汇编权、翻译权、印刷权及电子版的复制权、信息网络传播权与发行权等版权的特殊声明,即视作该文章署名作者同意将该文章的汇编权、翻译权、印刷权及电子版的复制权、信息网络传播权与发行权授予本刊,本刊有权授权本刊合作数据库、合作媒体等合作伙伴使用。同时,本刊支付的稿酬已包含上述使用的费用,特此声明。