在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 ;結束匯編