X86汇编代码分析-函数调用

1)

int add(int i, int j)
{
    return i + j;
}

int main()
{
    int a = 1;
    int b = 7;
    a = add(a, b);
    printf("%d\n",a);
}

汇编代码:

	.file	"ex3.c"
	.text
	.globl	add
	.type	add, @function
add:
.LFB0:
	.cfi_startproc
	pushq	%rbp # rbp入栈, 把rbp里的值压入堆栈。即当前rsp-4出的值变为rbp的值,rbp本身的值不变。
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp # rsp 的值给rbp
	.cfi_def_cfa_register 6
	movl	%edi, -4(%rbp) # edi 给rbp地址-4, 1
	movl	%esi, -8(%rbp) # esi 给rbp地址-8, 7
	movl	-4(%rbp), %edx # 又把1 给 edx
	movl	-8(%rbp), %eax # 又把7 给 eax
#	movl	$1, %edx # 又把1 给 edx
#	movl	$7, %eax # 又把7 给 eax
	addl	%edx, %eax     # eax=eax+edx
	popq	%rbp    #  是把当esp指向的栈中的值(即之前push rbp进栈的rbp的值)赋给rbp
# 并且esp+4(dx的值改变,esp在pop之前指向的地方的值不变,还是之前ax进栈后的值,即堆栈里的那个值不会自动清零)     
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	add, .-add
	.section	.rodata
.LC0:
	.string	"%d\n"
	.text
	.globl	main
	.type	main, @function
main:
.LFB1:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp # 为什么知道是16 byte?
#	movl	$1, -8(%rbp) #  第1个参数
	movl	$1, 8(%rsp) 
#	movl	$7, -4(%rbp) # 第2个参数
	movl	$7, 12(%rsp)
	movl	-4(%rbp), %edx # 把7给edx
	movl	-8(%rbp), %eax # 把1给eax
	movl	%edx, %esi # edx 给esi, 7, 不是什么变址寄存器啊
	movl	%eax, %edi # eax 给edi, 1
	call	add
#	movl	%eax, -8(%rbp)
#	movl	-8(%rbp), %eax
	movl	%eax, %esi
	leaq	.LC0(%rip), %rdi
#	movl	$0, %eax
	call	printf@PLT
	movl	$0, %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE1:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0"
	.section	.note.GNU-stack,"",@progbits

大部分看得懂,小部分不知道什么意思。汇编是可以修改的,跟C语言差不多。

感觉Fortran更加麻烦一些。

	.file	"b3.frac.f90"
	.text
	.p2align 4,,15
	.globl	frac_
	.type	frac_, @function
frac_:
.LFB0:
	.cfi_startproc
	# frac(k,gij,b,u,i,j)
	movl	(%rdi), %r10d # k, 第一个参数。r10d为r10的低32位,因为k是整数
	movsd	(%rsi), %xmm0 # gij, 第2个参数,加载到xmm0的低64位。
	testl	%r10d, %r10d # test只是进行按位与,不进位。判断k是否为0。
	jle	.L10 # 算是一个技巧性的预处理,如果k==0,就直接结束。确实有为0的。
	pushq	%r12 # 被调用者保存
	.cfi_def_cfa_offset 16
	.cfi_offset 12, -16
	pushq	%rbp # 被调用者保存
	.cfi_def_cfa_offset 24
	.cfi_offset 6, -24
	leal	1(%r10), %r11d 
	pushq	%rbx
	.cfi_def_cfa_offset 32
	.cfi_offset 3, -32
	movslq	(%r9), %rax
	movslq	%r10d, %r9
	imulq	$1681, %r9, %rbx
	movslq	(%r8), %r12
	leaq	(%rax,%rax,4), %rdi
	leaq	(%rax,%rdi,8), %rbp
	leaq	(%rbx,%rbp), %rdi
	addq	%r12, %rdi
	cmpl	$2, %r10d
	leaq	(%rcx,%rdi,8), %rax
	jle	.L6
	movsd	(%rax), %xmm2
	leaq	0(%rbp,%r12), %rax
	movl	$3, %edi
	addq	%rbx, %rax
	salq	$3, %rax
	leaq	-53792(%rcx,%rax), %rbx
	leaq	-26896(%rcx,%rax), %r8
	leal	-3(%r10), %eax
	shrl	%eax
	imulq	$26896, %rax, %rax
	subq	%rax, %rbx
	.p2align 4,,10
	.p2align 3
.L4:
	movsd	13448(%r8), %xmm3
	subq	$26896, %r8
	movslq	%edi, %rax
	movapd	%xmm3, %xmm1
	subsd	%xmm2, %xmm1
	movsd	26896(%r8), %xmm2
	mulsd	-16(%rdx,%rdi,8), %xmm1
	addsd	%xmm1, %xmm0
	movapd	%xmm2, %xmm1
	subsd	%xmm3, %xmm1
	mulsd	-8(%rdx,%rdi,8), %xmm1
	addq	$2, %rdi
	cmpq	%rbx, %r8
	addsd	%xmm1, %xmm0
	jne	.L4
.L3:
	movq	%r9, %rdi
	movslq	%r11d, %r11
	addq	%r12, %rbp
	subq	%rax, %rdi
	imulq	$1681, %rdi, %rdi
	imulq	$13448, %r11, %r11
	imulq	$-13448, %r9, %r8
	addq	%rdi, %rbp
	leaq	(%rcx,%rbp,8), %rcx
	.p2align 4,,10
	.p2align 3
.L5:
	movsd	(%rcx), %xmm1
	leaq	(%rcx,%r11), %rdi
	subq	$13448, %rcx
	subsd	(%rdi,%r8), %xmm1
	mulsd	(%rdx,%rax,8), %xmm1
	addq	$1, %rax
	cmpl	%eax, %r10d
	addsd	%xmm1, %xmm0
	jge	.L5
	popq	%rbx
	.cfi_def_cfa_offset 24
	popq	%rbp
	.cfi_def_cfa_offset 16
	movsd	%xmm0, (%rsi)
	popq	%r12
	.cfi_def_cfa_offset 8
	ret
	.p2align 4,,10
	.p2align 3
.L10:
	.cfi_restore 3
	.cfi_restore 6
	.cfi_restore 12
	rep ret
	.p2align 4,,10
	.p2align 3
.L6:
	.cfi_def_cfa_offset 32
	.cfi_offset 3, -32
	.cfi_offset 6, -24
	.cfi_offset 12, -16
	movl	$1, %eax
	jmp	.L3
	.cfi_endproc
.LFE0:
	.size	frac_, .-frac_
	.ident	"GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0"
	.section	.note.GNU-stack,"",@progbits

你可能感兴趣的:(汇编,示例)