堆棧的生長方向從最本質的理解是堆棧入棧方向是從高地址向地址還是低地址向高地址。
從高地址向低地址生長一般叫做向下生長,也叫作逆向生長。
從低地址向高地址生長一般叫做向上生長,也叫作正向生長。
一般來說堆棧是逆向生長的。
51單片機的堆棧生長方向爲正向生長,因爲執行PUSH指令時先將SP的值加1再將指定的8位數據單元的內容入棧。
80x86微機的堆棧生長方向爲逆向生長,因爲執行PUSH指令時先將SP的值減2再將指定的16位數據單元內容入棧。高字節放高地址,低字節放低地址(小端模式)。
STM32的堆棧生長方向是逆向生長。
以下來自網友的測試代碼本人在PC機上運行,結果跟80x86一致。代碼的原理是利用遞歸函數兩次分配給變量的地址的不同來區別堆棧的生長方向。
#include <stdio.h>
static int stack_dir = 0;
static void find_stack_direction (void)
{
static char *addr = NULL;
char dummy;
if (addr == NULL)
{
addr = &dummy;
find_stack_direction ();
}
else
{
if (&dummy > addr)
stack_dir = 1;
else
stack_dir = -1;
}
}
void main(void)
{
find_stack_direction();
if(stack_dir==1)
printf("stack grew upward\n");
else
printf("stack grew downward\n");
}
運行結果如下:
另外一點:數組,字符串內部數據地址按順序增長
#include <stdio.h>
/*
1. 80x86系統堆棧逆向生長
2. 數組,字符串內部數據地址按順序增長
*/
int main()
{
int i;
int j;
int k[4];
printf("int i;\n");
printf("int j;\n");
printf("int k[4];\n");
printf("\ni的地址>j的地址>k的地址\n");
printf("&i=%d\n",&i);
printf("&j=%d\n",&j);
printf("&k=%d\n",&k);
printf("\n數組內部數據地址按順序增長\n");
printf("&k[0]=%d\n",&k[0]);
printf("&k[1]=%d\n",&k[1]);
printf("&k[2]=%d\n",&k[2]);
printf("&k[3]=%d\n",&k[3]);
return 0;
}