Electronic – Confusion about ADR in ARM (assembly code)

armassemblycregister

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 an ADD or SUB 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, but ADR will take care of this when reassembled.

The instruction B sumi is just an unconditional jump to the address given by sumi (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) of R14 register - remember that the latter was previously modified by the ADR instruction. So the program continues jumping to the address given by the label cnt1.

When programming subroutines in Assembly, usually a combination of the B and BL jump instructions is employed - the latter (branch and link) already stores the return address into R14 (LR - link register).