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
 

结束主要