I do static analysis of ARM assembly code (I can't debug it).

When I look on argument that in SP+0x<SomeOffset> I can find what I'm looking for, but if I look a few lines further down I see that this argument is not there.

Which ARM, command is influencing the stack pointer (SP) position?

I don't see any add/sub to SP, the only commands that I see is ldr and str from SP and to SP +function BL that not touch on this argument.

I think that even I call to function, when I finish it the SP need to be same, and store to SP+offset or load from SP+offset don't need to change the SP.


There is no specific stack pointer register in ARM. By convention R13 is used as the stack pointer. There is no specific push and pop style stack pointer operands either.

Pushing and popping from the stack is carried out using the STM (store to memory) and LDM (load from memory) operands. These operands can be modified with the post fixes IA and DB. IA is increment after, and DB is decrement before.

So STMDB means store to memory, decrementing before the store. I.e. pushing on to a full descending stack. The inverse of this would be LDMIA which is popping from a full descending stack.

Alternatively you can have STMIA and LDMDB which means pushing and popping on to and off of an empty ascending stack.

FD is the synonym for full descending and EA is the synonym for empty ascending. So STMDB and STMFD are the same. LDMIA, LDMFD are the same. And so on...

So a full instruction would be for example...

STMDB R13!, {R0 - R3}

Which means push R0, then R1, then R2 and then R3 on to a full descending stack using R13 as the stack point. The address being written too is updated for each registered pushed. The ! means write back and means that R13 is updated with the final address so it can be used again.

BL (branch with link) does NOT affect the stack or the stack pointer. It merely copies the current PC (R15) in to link (R14) before the jump. A simple...

MOV R14, R15

... will return you back to the original address. However many may pop link straight in to PC at the end of a subroutine. For example...

STMFD R13!, {R0, R1, R14}
// Do stuff
LDMFD R13!, {R0, R1, R15} // pop link straight in to PC meaning return.
  • 1
    in fact the newer ARM architectures do standardize R13 as SP, and STMFD/ LDMFD instructions using it as PUSH/POP.
    – Igor Skochinsky
    Jul 4 '18 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.