Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PUSH and POP order in ARM

Tags:

stack

arm

I'm trying to understand the start and end of functions in ARM assembly:

PUSH {R0-R2, LR}
POP {R0-R2, PC}

Looking at this piece of code in IDA here's what I understood (Lets assume SP is 0x100):

PUSH R0 ; sp = 0xFC
PUSH R1 ; sp = 0xF8
PUSH R2 ; sp = 0xF4
PUSH LR ; sp = 0xF0
POP R0 ; sp = 0xF4
POP R1 ; sp = 0xF8
POP R2 ; sp = 0xFC
POP PC ; sp = 0x100

It seems like PC gets the value of R0, when it should get the value of LR.
Shouldn't PC get the value of LR?

like image 752
NotGI Avatar asked Mar 07 '23 16:03

NotGI


2 Answers

When you PUSH or POP a bunch of registers, they always go into memory in the same relative positions, regardless of direction. The lowest-numberd register is stored at and loaded from the lowest address. So in this example everything will go back to the original register, except LR->PC.

To put that another way, imagine the PUSH as if it was storing {LR,R2,R1,R0}.

See the User Guide / Instruction Set reference for your favourite Arm 32-bit processor series; LDM and STM.

like image 143
NickJH Avatar answered Mar 19 '23 12:03

NickJH


A POP instruction with PC in its register list is a branch instruction to the value being popped out of the stack. So for

POP {R0, PC} ~= MOV PC,R0 ; Except that R0 is on the stack

like image 28
Hazem Abaza Avatar answered Mar 19 '23 12:03

Hazem Abaza