BL 指令 ARM - 它是如何工作的
BL instruction ARM - How does it work
我正在学习 ARM Assembly,但我现在卡住了。
我知道 Link 寄存器,如果我没记错的话,它会在函数调用完成时保存 return 的地址。
所以如果我们有类似的东西(取自 ARM 文档):
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之后,Link寄存器的值就是1对吧?
然后程序转到那里的方法,然后它使用 Link 寄存器的值来知道到哪里去 return。
如果我们现在跳到地址 6,我被困在那里,我们知道什么 BL 将下一条指令的地址复制到 lr(r14,link 寄存器)。
所以现在它会复制sub的地址是一个子程序(什么是子程序??)+ rom(这是一个数字?)或sub + rom的地址(我不知道这是什么可能是)。
但一般来说,什么时候需要BL呢?为什么我们要在上面的例子中使用它?有人可以给我一个我们真正需要它的例子吗?
谢谢!
好像有点乱。这是一个解释:
B
指令将分支。它跳转到另一条指令,并且没有 return 预期。 Link 寄存器 (LR) 未被触及。
BL
指令会分支,但也会link。 LR会加载BL
后指令在内存中的地址,而不是BL
后执行的指令。然后可以使用 LR 从分支 return。
示例:
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会被覆盖,所以你将无法return。常见的解决方案是用 PUSH {LR}
将 LR 保存在堆栈上,并在 returning 之前用 POP {LR}
恢复它。您甚至可以在单个 POP {PC}
中恢复和 return :这将恢复 LR 的值,但在程序计数器中,有效地 returning 函数。
包括'emu8086.inc'
.堆栈 100h
.型号小
。数据
。代码
主进程
打印 'Enter First No:'
mov ah,01h
int 21h
sub al,48
mov bl,al
mov dl,10
mov ah,02h
int 21h
mov dl,13
mov ah,02h
int 21h
print 'Enter Second No:'
mov ah,01h
int 21h
sub al,48
add bl,al
add bl,48
mov dl,10
mov ah,02h
int 21h
mov dl,13
mov ah,02h
int 21h
print 'your sum is :'
mov dl,bl
mov ah,02h
int 21h
main endp
结束主要
我正在学习 ARM Assembly,但我现在卡住了。
我知道 Link 寄存器,如果我没记错的话,它会在函数调用完成时保存 return 的地址。
所以如果我们有类似的东西(取自 ARM 文档):
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之后,Link寄存器的值就是1对吧?
然后程序转到那里的方法,然后它使用 Link 寄存器的值来知道到哪里去 return。
如果我们现在跳到地址 6,我被困在那里,我们知道什么 BL 将下一条指令的地址复制到 lr(r14,link 寄存器)。
所以现在它会复制sub的地址是一个子程序(什么是子程序??)+ rom(这是一个数字?)或sub + rom的地址(我不知道这是什么可能是)。
但一般来说,什么时候需要BL呢?为什么我们要在上面的例子中使用它?有人可以给我一个我们真正需要它的例子吗?
谢谢!
好像有点乱。这是一个解释:
B
指令将分支。它跳转到另一条指令,并且没有 return 预期。 Link 寄存器 (LR) 未被触及。
BL
指令会分支,但也会link。 LR会加载BL
后指令在内存中的地址,而不是BL
后执行的指令。然后可以使用 LR 从分支 return。
示例:
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会被覆盖,所以你将无法return。常见的解决方案是用 PUSH {LR}
将 LR 保存在堆栈上,并在 returning 之前用 POP {LR}
恢复它。您甚至可以在单个 POP {PC}
中恢复和 return :这将恢复 LR 的值,但在程序计数器中,有效地 returning 函数。
包括'emu8086.inc'
.堆栈 100h .型号小 。数据 。代码 主进程 打印 'Enter First No:'
mov ah,01h
int 21h
sub al,48
mov bl,al
mov dl,10
mov ah,02h
int 21h
mov dl,13
mov ah,02h
int 21h
print 'Enter Second No:'
mov ah,01h
int 21h
sub al,48
add bl,al
add bl,48
mov dl,10
mov ah,02h
int 21h
mov dl,13
mov ah,02h
int 21h
print 'your sum is :'
mov dl,bl
mov ah,02h
int 21h
main endp
结束主要