C x86_64-linux-gnu:为什么堆栈指针从中减去?

C x86_64-linux-gnu:为什么堆栈指针从中减去?,c,linux,assembly,x86-64,C,Linux,Assembly,X86 64,我正在将以下代码段编译成汇编 void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; } void main() { function(1,2,3); } 这是函数 function: pushq %rbp movq %rsp, %rbp subq $48, %rsp ; why is 48 being subtracted from the sta

我正在将以下代码段编译成汇编

void function(int a, int b, int c) {
   char buffer1[5];
   char buffer2[10];
}

void main() {
  function(1,2,3);
}
这是
函数

function:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $48, %rsp ; why is 48 being subtracted from the stack pointer?
    movl    %edi, -36(%rbp)
    movl    %esi, -40(%rbp)
    movl    %edx, -44(%rbp)
    movq    %fs:40, %rax
    movq    %rax, -8(%rbp)
    xorl    %eax, %eax

我在一台64位机器上运行这个程序,所以我认为三个8字节的字足够容纳
buffer1
buffer2

,乍一看,这似乎是内存对齐的问题。更详细地说,我要特别注意乔什·佩里的回答:

维基百科在这里也谈到了这一点:


简而言之,
char buffer1[5]
将创建两个64字节的字(chars 1-4和5+)。如果没有,则每次您参考
buffer2
,系统都必须执行至少两个操作,以获得
buffer2

对齐的正确起点,这可能是一个问题。可能重复和相关,请参阅。你应该重新考虑接受下面的答案。我认为这是可以改进的,通过将你标记为被接受,你就表明你不想要更多(可能更好)的答案。上面,jww假设你的问题是“为什么下降,而不是上升?”另一个问题可能是“为什么改变,而不是保持不变?”你在另一个不清楚的问题上谈论尺寸点的事实。请解释你的问题是什么。也许通过描述您期望的替代方案。五个字节的数组将需要五个字节。它可能被放置在一个漂亮的64位边界上,并且最有可能在它后面的三个字节中不放置任何内容(对于下一个数组,它甚至是8个字节),但是它不会像那样分割数组的元素。除非您使用的系统
char
为16位,否则
char
按C定义为一个字节,而
char
指针则不是。char数组是一个char指针,在64位CPU上是64位的。很明显,我不能肯定我的答案是正确的,但乍一看,我认为这是内存对齐问题。编译器处理5字符数组的方式不同于处理5个单独的字符。不,数组不是指针。它可以衰减为指向其第一个元素的指针,但数组本身是一个单独的连续对象。我的理解是,指向一个5字符内存块的指针大致相当于一个5字符数组。指针只指向内存中的一个位置。数组声明一个内存块并指向它。我也不确定,所以我完全承认我可能错了或误解了什么。