【发布时间】:2021-04-12 10:11:04
【问题描述】:
我正在编写一个使用 ARM 程序集作为气泵接口的程序。用户选择他们想要泵送的汽油等级,然后宣布他们想要花费的金额。由于无论汽油的等级如何,都会对该输入执行相同的检查,因此我想使用相同的代码块。我希望我的代码使用bl 和bx lr,如here 所示,但我做错了什么。这是我的代码示例:
get_grade:
cmpne r1, #'R'
beq pump_regular
cmpne r1, #'P'
beq pump_premium
pump_regular:
ldr r0, =strSelRegular
bl printf
bl prompt_amount
@ do other things
pump_premium:
ldr r0, =strSelPremium
bl printf
bl prompt_amount
@ do other things
prompt_amount:
ldr r0, =numInputPattern
ldr r1, =intBuyAmt
bl scanf
@ check to make sure the input is valid
@ if not, b prompt_amount
bx lr
这个程序可以编译,但不符合我的预期。一旦到达prompt_amount 的末尾,它就会挂起。我已经在论坛帖子和 keil 文档中搜索了几个小时,但无济于事。非常感谢任何帮助。
【问题讨论】:
-
我不太明白你的代码。入口点在哪里?为什么
get_grade没有返回指令?您需要注意的另一个问题是每个bl指令都会覆盖lr寄存器。因此,为了能够从您的函数返回,您需要在入口处将lr保存在堆栈中,并在最后将其弹出。您可以使用push {lr}和pop {pc}来执行此操作,将pop指令与函数返回相结合。 -
@fuz:为了保持堆栈对齐,您通常想要执行类似
push {r4, lr}/pop {r4, pc}之类的操作,即使您实际上不需要保存/恢复额外的调用保留寄存器。 (IIRC,ARM Linux 上的 ABI 在调用前保持 8 字节堆栈对齐) -
您正在用
bl覆盖lr。而且由于您通过bx lr从函数返回,它一直分支到bx lr,唉,它挂起。
标签: assembly raspberry-pi arm