Reputation: 169
I am writing assembly code using the ARM Cortex-M0 instruction set. Since I have pushed quite a large number of elements into the stack, is there any way I can completely clear the stack, without popping the elements one by one? Some guidance would be appreciated
Upvotes: 0
Views: 5442
Reputation: 1820
To add some additional information to the first part of @Realtime Rik's answer, the initial value for SP
(specifically MSP
) is loaded from the first entry in the vector table. Depending on your micro and the boot modes, the location of the vector table may differ.
If the vector table has not been relocated (without copying this value), you can access the initial stack pointer with the following pseudo-C:
void * sp = *(SCB->VTOR);
The SCB
contains some core configuration registers, one of which is VTOR
or vector table offset register. This essentially contains the current address of the vector table. By dereferencing this register, we are accessing the first element of the table pointed to by VTOR
, which is where the initial stack pointer should be stored.
If you're writing a bootloader, for example, you can do a similar thing, except instead of looking at SCB->VTOR
, you'd need to look at the location where you specify the application to start. The example code from ST's USB bootloader is as follows:
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) USBD_DFU_APP_DEFAULT_ADD);
In this case, they have the default address for the vector table, cast it to a pointer, dereference it reading the first entry in the table, and set MSP
to that value. This is all just before jumping to the application.
Upvotes: 1
Reputation: 1704
If you want to completely discard any data on the stack, for example if you are calling a function that will never return (and you have taken copies of any parameters passed in) then you can simply set the SP to its initial value (or any other valid value). However remember that you will have then lost all the data originally stored on the stack.
If you want to retrieve the data into registers then the LDM (LDMIA) instruction. On an M0 you can only load data into R0-R7 (unlike and M3/4). The M0/1 uses the ARMv6-M instruction set, the M3 uses the ARMv7-M and M4 uses ARMv7E-M. The ARM Generic User guide for the instruction set you are using should help.
Upvotes: 2