C中堆栈上参数和变量的顺序

时间:2021-02-04 17:11:55

标签: c stack

几年前,我为我的学生整理了这个小小的内存地址探索,以帮助他们理解指针、数组、堆栈和堆。

我刚刚在新环境(AWS Linux 服务器上的 gcc)中编译并运行它,foo 的参数顺序与我预期的不同。与函数参数(a1、b1 和 c1)相比,局部函数变量(d1 和 e1)现在具有更高的地址。

函数foo中参数/变量的地址如下:

<块引用>
&a1: fa2740fc
&b1: fa2740f0
&c1: fa2740e8
&d1: fa27410c
&e1: fa274100

关于为什么变量 d1e1 的地址高于 a1b1 的任何想法>c1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int* foo (int a1, int b1[], int *c1)
{
  int d1 = *c1 + a1;
  int *e1;
  
  e1 = malloc (sizeof(int));

  printf ("5) Addresses of arguments/variables of foo:\n");
  printf ("   Update your stack sketch.\n");
  printf ("     &a1: %x\n", &a1);
  printf ("     &b1: %x\n", &b1);
  printf ("     &c1: %x\n", &c1);
  printf ("     &d1: %x\n", &d1);
  printf ("     &e1: %x\n\n", &e1);

  printf ("6) Values of arguments/variables in foo:\n");
  printf ("   Include these on your stack sketch as well.\n");
  printf ("     a1: %x\n", a1);
  printf ("     b1: %x\n", b1);
  printf ("     c1: %x\n", c1);
  printf ("     d1: %x\n", d1);
  printf ("     e1: %08x\n\n", e1);

  printf ("7) *c1 == %x, why?  Explain using your stack drawing.\n\n", *c1); 
  
  printf ("8) e1 is a reference to an integer, much like c1.  Why is e1 so\n ");
  printf ("   different in value?\n\n");

  return e1;
}


int main ()
{
  int a = 5;
  int b[] = {8, 14, -7, 128, 12};
  int c = 10;
  int d = 14;

  printf ("1) Locations...\n");
  printf ("   Use these locations to sketch the stack.\n");
  printf ("     &a: %x\n", &a);
  printf ("     &b: %x\n", &b);
  printf ("     &c: %x\n", &c);
  printf ("     &d: %x\n\n", &d);
  
  printf ("2a) Values:\n");
  printf ("   Why does b != 8?\n");
  printf ("     a: %x\n", a);
  printf ("     b: %x\n", b);
  printf ("     c: %x\n", c);
  printf ("     d: %x\n\n", d);

  printf ("2b) Values:\n");
  printf ("   What memory address is *b accessing?\n");
  printf ("     *b: %x\n\n", *b);
  
  printf ("3) Notice that the following increase by 4 each, why?\n");
  printf ("     &(b[0]): %x\n", &(b[0]));
  printf ("     &(b[1]): %x\n", &(b[1]));
  printf ("     &(b[2]): %x\n", &(b[2]));
  printf ("     &(b[3]): %x\n\n", &(b[3]));

  printf ("4) Pointers can be added, but the addition might have interesting results.\n");
  printf ("   Explain why b + 1 != b + 1 in the normal way of thinking about addition.\n");
  printf ("     b:   %x\n", b);
  printf ("     b+1: %x\n", b+1);
  printf ("     b+2: %x\n", b+2);
  printf ("     b+3: %x\n\n", b+3);
  
  foo (a, b, &c);
}

1 个答案:

答案 0 :(得分:1)

正如@trentcl 所评论的,显然参数 a1、b1 和 c1 是通过寄存器而不是在堆栈上传递的。编辑 foo 以获取额外的 8 个虚拟参数会强制将 a1、b1 和 c1 作为参数传递到堆栈上,其地址高于本地参数。