|
What is eight-byte stack alignment?
Eight byte stack alignment is a requirement of the Procedure Call Standard for the ARM Architecture [AAPCS]. This specifies that functions must maintain an eight-byte aligned stack address (for example: 0x00, 0x08, 0x10, 0x18, 0x20) on all external interfaces. In practice this requirement is met if:[li]At each external interface, the current stack pointer (SP) is a multiple of eight bytes.[/li][li]Your OS maintains eight-byte stack alignment on its external interfaces, for example, on task switches [/li]
Eight-byte stack alignment is of particular benefit to processors supporting LDRD and STRD instructions, for example, processors based on ARM architecture v5TE and later. If the stack is not eight-byte aligned the use of LDRD and STRD might cause an alignment fault, depending on the target and configuration used.Eight-byte stack alignment in RVCT and the ARM Compiler toolchain
In the RVCT v2.0 and above, all generated code and C library code will maintain eight-byte stack alignment on external interfaces. The generated code may not keep the stack eight-byte aligned internally, for example, in leaf functions. However all generated code will keep the stack eight-byte aligned providing that it is already correctly aligned at the entry to the function. The compiler will not generate code to correct a misaligned stack.
Please be aware that eight-byte stack alignment is not new to RVDS. ADS does maintain eight-byte stack alignment, only the alignment of double and long long has changed between ADS and RVDS. In ADS double and long long data types were four-byte aligned ("EBA4"), unless -Oldrd or __align were used. In RVCT 2.0 and later, double and long long data types are now eight-byte aligned ("EBA8"), unless --apcs /adsabi is used.
The RVCT 3.1 compiler and earlier supports the option --apcs /adsabi to compile code that is compatible with the old ADS ABI. However, this option was deprecated and finally removed in RVCT 4.0.
The ARM Compiler toolchain check eight byte stack alignment using two build attributes REQUIRE8 and PRESERVE8, these can either be true or false. These are embedded into the object files and executables generated by the tools. REQUIRE8 is used to indicate that the code requires the stack pointer to be eight-byte aligned. PRESERVE8 is used to indicate that the code preserves eight-byte stack alignment.
The assembler uses the REQUIRE8 and PRESERVE8 directives to indicate whether REQUIRE8 and PRESERVE8 build attributes should be true or false. If you omit PRESERVE8 the assembler will decide whether to set the PRES8 build attribute or not, by examining instructions that modify SP. ARM recommends that you specify PRESERVE8 explicitly. If your assembly requires the stack to be eight byte aligned, for example, an LDRD using SP, you should specify the REQUIRE8 directive.
In RVCT 2.1 and later the assembler (armasm) can generate a warning if it detects a stack access that would leave the stack not eight-byte aligned. This can be enabled by adding --diag_warning 1546 to your assembler command line.
The REQUIRE8 and PRESERVE8 build attributes set by the compiler and assembler are used by the linker to prevent functions that require eight-byte alignment calling functions that do not preserve eight-byte alignment. If this occurs the linker will generate an error, for example:
Error: L6238E: foo.o(.text) contains invalid call from '~PRES8' function to 'REQ8' function
Please see the Errors and Warnings document for your toolchain for further information about this error message. |
|