Stack pointer alignment 8 bytes with 4 bytes in the ARM assembly

How to align stack pointer with 8 bytes, which is now 4 bytes in ARM. According to my understanding, the stack pointer is 4 bytes if it points to some address, for example, 0x4, 0x8,0x12 and 0x16 and so on.

So, adding a stack pointer to 8 bytes, it should point to addresses like 0x8, 0x16, 0x24 and 0x32, etc.

Now, how to align a 4-byte stack pointer with an 8-byte aligned pointer?

+2
source share
4 answers

Due to stack reduction

bic sp, sp, #7 

should be enough. With EABI, you can use r12 or r0-r3 to (re) save the previous value.

All this needs to be done only in the assembly; within C, you can rely on a properly aligned stack pointer and try to change it, perhaps you will damage your program.

Compilers take care of proper alignment; inconsistent stacks can occur when interrupts are called. Some CPUs (e.g. Cortex-M3) have special registers (STKALIGN) that can be used to input irqs with 8-bit stack alignment.

+2
source

Do not try to align sp yourself yourself, instead of push one more register to get alignment. For example, instead of

 push {r3, r4, lr} 

add another register to the list to easily align to 8.

 push {r1, r3, r4, lr} 

This may seem like additional memory access, but in general, caches work with wider bit vectors than with native word sizes.

One more note: you do not need to force yourself to align the stacks correctly if you are not making external calls or receiving. Therefore, if you have a closed box assembly procedure that does not cause calls to the outside world or does not receive them, you can live with a broken stack alignment if it does not bite your own loads.

+2
source

To move the pointer to the nearest border of 8 bytes, but leave it unmodified if it is already a multiple of 8 (pseudocode - you need to add some casts if this is done in C):

 p = (p + 7) & ~7; 

or similarly move it to the nearest border of 8 bytes:

 p = p & ~7; 
+1
source

If you write sheet functions (no subroutine calls), don't worry.

You do a great job with a 4-byte aligned SP, as this requirement is associated with the ldrd and strd instructions, which require an address that is a multiple of eight. Therefore, if the function you are writing does not call a subroutine unknown to you, this is not necessary. (ldrd and strd are so rarely used)

SP is already aligned by 8 bytes when your function is called from a higher level language.

If you want the SP to be 8-byte aligned, either do not touch it, or keep only an even number of registers.

+1
source

All Articles