在ARM匯編語言中,,子程序調(diào)用是通過BL指令來完成的。BL指令的語法格式如下:
BL subname
其中:subname是被調(diào)用的子程序的名稱,。BL指令完成2個(gè)操作,,即將子程序的返回地址放在LR寄存器中,,同時(shí)將PC寄存器值設(shè)置成目標(biāo)子程序的第一條指令地址。
在返回調(diào)用子程序時(shí),,轉(zhuǎn)移鏈接指令保存到LR寄存器中的值需要拷貝回程序寄存器PC,。對(duì)于最簡單的子程序,一條MOV指令就可完成子程序的返回,,例如:
SUB2 …
MOV PC,,R14 ;把R14拷貝到R15來返回
其實(shí),,任何數(shù)據(jù)處理指令都可用來計(jì)算返回地址,,但是MOV指令時(shí)至今最常見的形式。碎玉在子程序中出現(xiàn)嵌套調(diào)用時(shí),,鏈接寄存器LR中的返回地址可能會(huì)在第二次調(diào)用時(shí)被覆蓋,,所以需要將返回地址壓入堆棧來進(jìn)行保存。在子程序返回時(shí),,返回地址和保存的工作寄存器都可用多寄存器存取指令恢復(fù),。例如:
SUB1 STMFD R13!,{R0-R2,R14} ;保存工作寄存器和鏈接
BL SUB2
…
LDMFD R13!,{R0-R2,,PC} ;恢復(fù)工作寄存器并返回
需要注意的是,,返回地址是直接恢復(fù)到程序計(jì)數(shù)器PC,而不是鏈接寄存器LR,。這種單元恢復(fù)和返回指令是非常有用的,。
下面是一個(gè)子程序調(diào)用的簡單例子。子程序DOADD完成加法運(yùn)算,,操作數(shù)放在R0和R1寄存器中,,結(jié)果放在R0中。
AREA EXAMPLE,,CODE,,READONLY
ENTRY
Start MOV R0,#10 ,;設(shè)置輸入?yún)?shù)R0
MOV R1,,#3 ;設(shè)置輸入?yún)?shù)R1
BL Doadd ,;調(diào)用子程序Doadd
…
Doadd ADD R0,,R0,R1 ,;子程序
MOV PC,,LR ,;從子程序中返回
END ;結(jié)束匯編