I'm confused on what's happening with ADR R14,cnt1
. Is cnt1
signifying the end of the program? And if so how will B sumi
get called? In the ARM manual, it said that ADR
takes in PC
but I don't see that here.
c++:
s = 0;
for(i=1;i<=n;i++)
s += i;
assembly:
sumi:
MOV R0,#0
MOV R1,#1
next:
CMP R1,R2
BGT end
ADD R0,R0,R1
ADD R1,R1,#1
B next
end: MOV PC,R14
ADR R14,cnt1
B sumi
cnt1: ; ...
Best Answer
At the beginning of the program, the ARM pseudo-instruction
ADR R14, cnt1
loads an address (cnt1
- end of this part of the program) into a register (R14
). In practice,ADR
is replaced by anADD
orSUB
instruction involving the contents of the PC (R15
). The calculation is based on the offset between the PC and the address in question - taking into account that the PC displacement due to the operation of ARM pipeline. It's easier let the assembler calculate the addresses for you. If the code is changed, the addresses as well, butADR
will take care of this when reassembled.The instruction
B sumi
is just an unconditional jump to the address given bysumi
(start of the subroutine).At the end of the loop, the
MOV PC,R14
instruction is executed, causing the PC to be loaded with the content (an address) ofR14
register - remember that the latter was previously modified by theADR
instruction. So the program continues jumping to the address given by the labelcnt1
.When programming subroutines in Assembly, usually a combination of the
B
andBL
jump instructions is employed - the latter (branch and link) already stores the return address intoR14
(LR - link register).