本文介绍了BL指令ARM-如何运作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习ARM汇编,并且现在还停留在某些东西上.

I am learning ARM Assembly, and I am stuck on something right now.

我知道链接寄存器,如果我没记错的话,该寄存器保存了函数调用完成后要返回的地址.

I know about the Link Register, which if I'm not wrong holds the address to return to when a function call completes.

因此,如果我们有类似的内容(摘自ARM文档):

So if we have something like that (taken from the ARM documentation):

0 | here
1 |   B there
2 |
3 |   CMP R1, #0
4 |   BEQ anotherfunc
5 |
6 |   BL sub+rom ;  Call subroutine at computed address.

那么,如果我们认为左侧的列是每条指令的地址,那么在地址1处的B之后,链接寄存器的值是否为1右?

So, if we think of the column at the left as addresses of each instruction, then after the B there at address 1, the Link Register holds the value of 1 right?

然后程序转到那里的方法,然后使用链接寄存器的值来知道要返回的位置.

Then the program goes to the method there and then it uses the value of the Link Register to know where to return.

如果我们现在跳到卡住的地址6,我们知道哪个BL将下一条指令的地址复制到lr(r14,链接寄存器)中.

If we skip to address 6 now, where I am stuck, we know what BL copies the address of the next instruction into lr (r14, the link register).

所以现在它将复制sub的地址,sub的内容是一个子例程(什么是子例程?)+ rom(这是一个数字?)或sub + rom的地址(我不知道这可能是什么) ).

So now it would copy the address of sub which is a subroutine (what is a subroutine??) + rom (which is a number?) or the address of sub+rom (I don't know what this could be).

但是,总的来说,我们什么时候需要BL?为什么在上面的示例中需要它?有人可以给我一个我们真正需要它的例子吗?

But in general, when would we need BL? Why do we want it in the example above? Can someone give me an example where we would really need it?

谢谢!

推荐答案

似乎有些混乱.这是一个解释:

It seems there is a bit of confusion. Here is an explanation :

B指令将分支.它跳转到另一条指令,并且没有返回预期.链接寄存器(LR)未被触摸.

The B instruction will branch. It jumps to another instruction, and there is no return expected. The Link Register (LR) is not touched.

BL指令将分支,但也会链接. LR将在存储器中加载BL之后的指令的地址,而不是BL之后执行的指令的地址.然后可以使用LR从分支返回.

The BL instruction will branch, but also link. LR will be loaded with the address of the instruction after BL in memory, not the instruction executed after BL. It will then be possible to return from the branch using LR.

示例:

start:
01:  MOV r0, r2     ; some instruction
02:  B there        ; go there and never return !

there:
11:  MOV r1, r0         ; some instruction
12:  BL some_function   ; go to some_function, but hope to return !
                        ; this BL will load 13 into LR
13:  MOV r5, r0
14:  BL some_function   ; this BL will load 15 into LR
15:  MOV r6, r0


some_function:
     MOV r0, #3
     B LR               ; here, we go back to where we were before

如果要在函数内调用另一个函数,LR将被覆盖,因此您将无法返回.常见的解决方案是使用PUSH {LR}将LR保存在堆栈中,并在使用POP {LR}返回之前将其还原.您甚至可以在单个POP {PC}中恢复并返回:这将恢复LR的值,但是在程序计数器中可以有效地返回该函数.

If you want to call another function inside a function, LR will be overwritten, so you won't be able to return. The common solution is to save LR on the stack with PUSH {LR}, and restore it before returning with POP {LR}. You can even restore and return in a single POP {PC} : this will restore the value of LR, but in the program counter, effectively returning of the function.

这篇关于BL指令ARM-如何运作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 19:32