ARM子程序里再调用函数的问题

时间:2022-02-28 04:46:21
有人能给个ARM子程序里面在调用函数的例子吗
子程序的返回值应该是 MOV PC LR
那调用函数的返回值应该是什么 最好能给个完整的例子 先谢了!

8 个解决方案

#1


可以查一下相关的ARM指令

#2


给个例子。

LDR   R0, PARAM2 
STR   R0, [SP, #-4]! ;将参数推入堆栈
LDR   R0, PARAM1
STR  R0, [SP, #-4]!
BL   SUB1
2020 LDR  R0, [SP] ;保存SUB1的结果
STR  R0, RESULT
ADD  SP, SP, #8 ;恢复堆栈

子程序
SUB1 
STMFD  SP!, {R0-R3, FP,LR}
ADD  FP, SP, #16 ;计算帧指针
LDR  R0, [FP, #8] ;载入参数1
LDR  R1, [FP, #12] ;载入参数2
LDR  R2, PARAM3 ;载入参数3
STR  R2, [SP, #-4]! ;将参数3推入堆栈
BL  SUB2
LDR  R2, [SP], #4 ;将SUB2的结果弹出并存储在R2中,并递增SP
STR  R3, [FP, #8] ;将结果推入堆栈
LDMFD  SP!, {R0-R3, FP, PC} ;恢复寄存器并返回

SUB2 
STMFD  SP!, {R0, R1, FP, LR}
ADD  FP, SP, #8 ;载入结构指针
LDR  R0, [FP, #8] ;载入参数
STR  R1, [FP, #8] ;将结果推入堆栈
LDMFD  SP!, {R0, R1, FP, PC}

#3


例子有点复杂 一时不太理解
比如做个简单的程序 像算个5+2*3 用两个子程序完成 应该怎么写的 谢谢

#4


MOV PC LR
这个是说子函数调用结束时把主程序中的调用该子程序指令的下一条要执行的指令放到程序计数器pc中去,所以函数调用结束后能够顺利返回,这句话一般是自动执行的,不用写

你只需要在子程序的开头把pc,lr以及子程序中要用到的寄存器都压入堆栈保护,在子程序的末尾再从堆栈中恢复出来就可以了

#5


是不是就是

SUB1
STMFD SP!, {R0-R3, FP,LR} 
...............
BL SUB2 
LDMFD  SP!, {R0-R3, FP, PC}

SUB2
STMFD SP!, {R0, R1, FP, LR} 
........
LDMFD  SP!, {R0, R1, FP, PC} 

就行了?需不需要在子程序里面对FP和SP进行操作?

#6


引用 2 楼 aaa_tnt 的回复:
给个例子。

LDR  R0, PARAM2
STR  R0, [SP, #-4]! ;将参数推入堆栈
LDR  R0, PARAM1
STR R0, [SP, #-4]!
BL  SUB1
2020 LDR R0, [SP] ;保存SUB1的结果
STR R0, RESULT
ADD SP, SP, #8 ;恢复堆栈

子程序
SUB1
STMFD SP!, {R0-R3, FP,LR}
ADD FP, SP, #16 ;计算帧指针
LDR R0, [FP, #8] ;载入参数1
LDR R1, [FP, #12] ;载入参数2
LDR R2, PARAM3 ;载入参数3
STR R2, [SP, #-4]! ;将参数3推入堆栈
BL SUB2
LDR R2, [SP], #4 ;将SUB2的结果弹出并存储在R2中,并递增SP
STR R3, [FP, #8] ;将结果推入堆栈
LDMFD  SP!, {R0-R3, FP, PC} ;恢复寄存器并返回

SUB2
STMFD SP!, {R0, R1, FP, LR}
ADD FP, SP, #8 ;载入结构指针
LDR R0, [FP, #8] ;载入参数
STR R1, [FP, #8] ;将结果推入堆栈
LDMFD  SP!, {R0, R1, FP, PC}
 好

#7


我需不需要在子程序里对FP和SP进行操作?还是在子程序的末尾再从堆栈中恢复出就够了?

#8


同样不是很清楚 我也刚学ARM 希望高手解答 帮顶!

#1


可以查一下相关的ARM指令

#2


给个例子。

LDR   R0, PARAM2 
STR   R0, [SP, #-4]! ;将参数推入堆栈
LDR   R0, PARAM1
STR  R0, [SP, #-4]!
BL   SUB1
2020 LDR  R0, [SP] ;保存SUB1的结果
STR  R0, RESULT
ADD  SP, SP, #8 ;恢复堆栈

子程序
SUB1 
STMFD  SP!, {R0-R3, FP,LR}
ADD  FP, SP, #16 ;计算帧指针
LDR  R0, [FP, #8] ;载入参数1
LDR  R1, [FP, #12] ;载入参数2
LDR  R2, PARAM3 ;载入参数3
STR  R2, [SP, #-4]! ;将参数3推入堆栈
BL  SUB2
LDR  R2, [SP], #4 ;将SUB2的结果弹出并存储在R2中,并递增SP
STR  R3, [FP, #8] ;将结果推入堆栈
LDMFD  SP!, {R0-R3, FP, PC} ;恢复寄存器并返回

SUB2 
STMFD  SP!, {R0, R1, FP, LR}
ADD  FP, SP, #8 ;载入结构指针
LDR  R0, [FP, #8] ;载入参数
STR  R1, [FP, #8] ;将结果推入堆栈
LDMFD  SP!, {R0, R1, FP, PC}

#3


例子有点复杂 一时不太理解
比如做个简单的程序 像算个5+2*3 用两个子程序完成 应该怎么写的 谢谢

#4


MOV PC LR
这个是说子函数调用结束时把主程序中的调用该子程序指令的下一条要执行的指令放到程序计数器pc中去,所以函数调用结束后能够顺利返回,这句话一般是自动执行的,不用写

你只需要在子程序的开头把pc,lr以及子程序中要用到的寄存器都压入堆栈保护,在子程序的末尾再从堆栈中恢复出来就可以了

#5


是不是就是

SUB1
STMFD SP!, {R0-R3, FP,LR} 
...............
BL SUB2 
LDMFD  SP!, {R0-R3, FP, PC}

SUB2
STMFD SP!, {R0, R1, FP, LR} 
........
LDMFD  SP!, {R0, R1, FP, PC} 

就行了?需不需要在子程序里面对FP和SP进行操作?

#6


引用 2 楼 aaa_tnt 的回复:
给个例子。

LDR  R0, PARAM2
STR  R0, [SP, #-4]! ;将参数推入堆栈
LDR  R0, PARAM1
STR R0, [SP, #-4]!
BL  SUB1
2020 LDR R0, [SP] ;保存SUB1的结果
STR R0, RESULT
ADD SP, SP, #8 ;恢复堆栈

子程序
SUB1
STMFD SP!, {R0-R3, FP,LR}
ADD FP, SP, #16 ;计算帧指针
LDR R0, [FP, #8] ;载入参数1
LDR R1, [FP, #12] ;载入参数2
LDR R2, PARAM3 ;载入参数3
STR R2, [SP, #-4]! ;将参数3推入堆栈
BL SUB2
LDR R2, [SP], #4 ;将SUB2的结果弹出并存储在R2中,并递增SP
STR R3, [FP, #8] ;将结果推入堆栈
LDMFD  SP!, {R0-R3, FP, PC} ;恢复寄存器并返回

SUB2
STMFD SP!, {R0, R1, FP, LR}
ADD FP, SP, #8 ;载入结构指针
LDR R0, [FP, #8] ;载入参数
STR R1, [FP, #8] ;将结果推入堆栈
LDMFD  SP!, {R0, R1, FP, PC}
 好

#7


我需不需要在子程序里对FP和SP进行操作?还是在子程序的末尾再从堆栈中恢复出就够了?

#8


同样不是很清楚 我也刚学ARM 希望高手解答 帮顶!