在从高地址到低地址增长的调用堆栈中,数据元素是从低内存地址保存到高内存地址还是反之?

时间:2016-08-30 15:13:56

标签: c mips callstack

在调用堆栈在内存中从高内存地址增长到低内存地址的架构中,假设堆栈指针最初位于更高的内存地址Y,并且在将整数参数保存到其上之后,堆栈指针转到较低的内存地址X.那么整数参数的第一个字节是X(较低地址)还是Y(较高地址)?

4 个答案:

答案 0 :(得分:2)

Endianness完全无关紧要,为什么甚至被提及。

为什么你不试试看?当然它是特定的编译器/调用约定,但使用您关心的编译器很容易理解。

void more_fun ( unsigned int, unsigned int );
void fun
(
    unsigned int a,
    unsigned int b,
    unsigned int c,
    unsigned int d,
    unsigned int e,
    unsigned int f
)
{
    more_fun(e,f);
}

00000000 <fun>:
   0:   8fa50014    lw  a1,20(sp)
   4:   8fa40010    lw  a0,16(sp)
   8:   08000000    j   0 <fun>
   c:   00000000    nop

答案 1 :(得分:2)

假设整数和寄存器的大小均为4个字节(在某个平台上)。然后有两种可能的情况:

  • 整数存储在SP中,然后SP递减:

          +---+
          |   |
          +   +
          | i |
          + n +      the integer that was pushed
          | t |
          +   +
    .     |   |      X
    .     +---+
    .     | u |
    .     + n +
    .     | u |
    .     + s +      unused (yet)
    .     | e |
    v     + d +
    SP -> |   |      Y
          +---+  
    
  • SP递减,然后整数存储在SP:

          +---+
          |   |
          +   +
          | ? |
          + ? +      previous push
          | ? |
          +   +
    .     |   |      X
    .     +---+
    .     |   |
    .     +  +
    .     | i |
    .     + n +      the integer that was pushed
    .     | t |
    v     +   +
    SP -> |   |      Y
          +---+
    

使用以下哪种方法取决于代码运行的平台。

请注意,根据标准,不需要堆栈。它只是大多数C(和其他语言)编译器的实现细节。

答案 2 :(得分:1)

Endianess和堆栈增长方向并不相关。如果在堆栈上存储32位整数,则根据字节顺序存储4个字节。堆栈/堆栈指针不知道/关心那里存储的内容,数字本身也不知道/关心它恰好在堆栈上分配。

因此,对于大端,MS字节将始终存储在最低地址。无论你在哪里分配它。

答案 3 :(得分:0)

你的comment仍在询问依赖于处理器的endian(以及处理器是否双向运行时的编译器。)对于MIPS,请参见thisthis - 它是双端。

@Rudy一样,您似乎想知道2 int s:AB是否在其地址位置定义了订单。 C规范没有规定它。这取决于所使用的编译器和选项 - 这一点在帖子中没有给出。