Through the C language compiled code analysis data alignment (Data Alignment) with parameter passing

C code

#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 Generating assembly code

	.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

Interpreted as follows

先看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



Published 21 original articles · won praise 3 · views 10000 +

Guess you like

Origin blog.csdn.net/wzq2009/article/details/103683309