C代码
#include <stdio.h>
typedef struct S {
short a;
int b;
long c;
long d;
long e;
long f;
long g;
long h;
short i;
} S;
void foo(S s) {
printf("%hd, %d, %ld, %ld, %ld, %ld, %ld, %ld, %hd\n",
s.a, s.b, s.c, s.d, s.e, s.f, s.g, s.h, s.i);
}
int main() {
S s = {1, 2, 3, 4, 5, 6, 7, 8, 9};
foo(s);
printf("%ld\n", sizeof(short));
}
gcc -S -g test.c
生成的汇编代码
.file "test_align.c"
.text
.Ltext0:
.section .rodata
.align 8
.LC0:
.string "%hd, %d, %ld, %ld, %ld, %ld, %ld, %ld, %hd\n"
.text
.globl foo
.type foo, @function
foo:
.LFB0:
.file 1 "test_align.c"
.loc 1 14 0
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
.loc 1 17 0
movzwl 72(%rbp), %eax
.loc 1 16 0
movswl %ax, %r9d
movq 64(%rbp), %r8
movq 56(%rbp), %rdi
movq 48(%rbp), %rsi
movq 40(%rbp), %r11
movq 32(%rbp), %r10
movq 24(%rbp), %rcx
movl 20(%rbp), %edx
.loc 1 17 0
movzwl 16(%rbp), %eax
.loc 1 16 0
cwtl
pushq %r9
pushq %r8
pushq %rdi
pushq %rsi
movq %r11, %r9
movq %r10, %r8
movl %eax, %esi
leaq .LC0(%rip), %rdi
movl $0, %eax
call printf@PLT
addq $32, %rsp
.loc 1 18 0
nop
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size foo, .-foo
.section .rodata
.LC1:
.string "%ld\n"
.text
.globl main
.type main, @function
main:
.LFB1:
.loc 1 20 0
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $64, %rsp
.loc 1 21 0
movw $1, -64(%rbp)
movl $2, -60(%rbp)
movq $3, -56(%rbp)
movq $4, -48(%rbp)
movq $5, -40(%rbp)
movq $6, -32(%rbp)
movq $7, -24(%rbp)
movq $8, -16(%rbp)
movw $9, -8(%rbp)
.loc 1 22 0
pushq -8(%rbp)
pushq -16(%rbp)
pushq -24(%rbp)
pushq -32(%rbp)
pushq -40(%rbp)
pushq -48(%rbp)
pushq -56(%rbp)
pushq -64(%rbp)
call foo
addq $64, %rsp
.loc 1 23 0
movl $2, %esi
leaq .LC1(%rip), %rdi
movl $0, %eax
call printf@PLT
movl $0, %eax
.loc 1 24 0
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size main, .-main
解析如下
先看struct 初始化后的栈分布图,设栈底为0:
栈顶 栈底
|--a---|--b--|----c-----|-----d----|----e-----|----f-----|----g-----|----h-----|----i-----|
-64 -60 -56 -48 -40 -32 -24 -16 -8 0
从栈分布情况可以看出struct里每个元素的起始地址都是自身长度的整数倍。
传参数的栈:
栈顶
|--a----b--|----c----|----d----|----e----|----f----|----g----|----h----|--i------|
从栈分布情况可以看出处理器传输数据是以8位为单位的。
从参数栈内取参, 现在设栈顶为0:
栈顶
|----返回地址----|----RBP----|--a--|--b--|----c----|----d----|----e----|----f----|----g----|----h----|--i------|
0 8 16 20 24 32 40 48 56 64 72