linux 64bit C 程序汇编分析

源码:

int foobar(int a, int b, int c)
{
    int xx = a + 2;
    int yy = b + 3;
    int zz = c + 4;
    int sum = xx + yy + zz;

    return xx * yy * zz + sum;
}

int main()
{
    return foobar(77, 88, 99);
}

汇编:

gcc -masm=intel -S z.c -o z.s

z.s 源码:

	.file	"z.c"
	.intel_syntax
	.text
.globl foobar
	.type	foobar, @function
foobar:
.LFB2:
	push	%rbp
.LCFI0:
	mov	%rbp, %rsp
.LCFI1:
	mov	DWORD PTR [%rbp-20], %edi
	mov	DWORD PTR [%rbp-24], %esi
	mov	DWORD PTR [%rbp-28], %edx
	mov	%eax, DWORD PTR [%rbp-20]
	add	%eax, 2
	mov	DWORD PTR [%rbp-16], %eax
	mov	%eax, DWORD PTR [%rbp-24]
	add	%eax, 3
	mov	DWORD PTR [%rbp-12], %eax
	mov	%eax, DWORD PTR [%rbp-28]
	add	%eax, 4
	mov	DWORD PTR [%rbp-8], %eax
	mov	%eax, DWORD PTR [%rbp-12]
	add	%eax, DWORD PTR [%rbp-16]
	add	%eax, DWORD PTR [%rbp-8]
	mov	DWORD PTR [%rbp-4], %eax
	mov	%eax, DWORD PTR [%rbp-16]
	imul	%eax, DWORD PTR [%rbp-12]
	imul	%eax, DWORD PTR [%rbp-8]
	add	%eax, DWORD PTR [%rbp-4]
	leave
	ret
.LFE2:
	.size	foobar, .-foobar
.globl main
	.type	main, @function
main:
.LFB3:
	push	%rbp
.LCFI2:
	mov	%rbp, %rsp
.LCFI3:
	mov	%edx, 99
	mov	%esi, 88
	mov	%edi, 77
	call	foobar
	leave
	ret
.LFE3:
	.size	main, .-main
	.section	.eh_frame,"a",@progbits
.Lframe1:
	.long	.LECIE1-.LSCIE1
.LSCIE1:
	.long	0x0
	.byte	0x1
	.string	"zR"
	.uleb128 0x1
	.sleb128 -8
	.byte	0x10
	.uleb128 0x1
	.byte	0x3
	.byte	0xc
	.uleb128 0x7
	.uleb128 0x8
	.byte	0x90
	.uleb128 0x1
	.align 8
.LECIE1:
.LSFDE1:
	.long	.LEFDE1-.LASFDE1
.LASFDE1:
	.long	.LASFDE1-.Lframe1
	.long	.LFB2
	.long	.LFE2-.LFB2
	.uleb128 0x0
	.byte	0x4
	.long	.LCFI0-.LFB2
	.byte	0xe
	.uleb128 0x10
	.byte	0x86
	.uleb128 0x2
	.byte	0x4
	.long	.LCFI1-.LCFI0
	.byte	0xd
	.uleb128 0x6
	.align 8
.LEFDE1:
.LSFDE3:
	.long	.LEFDE3-.LASFDE3
.LASFDE3:
	.long	.LASFDE3-.Lframe1
	.long	.LFB3
	.long	.LFE3-.LFB3
	.uleb128 0x0
	.byte	0x4
	.long	.LCFI2-.LFB3
	.byte	0xe
	.uleb128 0x10
	.byte	0x86
	.uleb128 0x2
	.byte	0x4
	.long	.LCFI3-.LCFI2
	.byte	0xd
	.uleb128 0x6
	.align 8
.LEFDE3:
	.ident	"GCC: (GNU) 4.1.2 20070115 (prerelease) (SUSE Linux)"
	.section	.note.GNU-stack,"",@progbits

现在我们只关注

main 函数和 foobar 这两个函数, 也就是下面这一块代码

foobar:
.LFB2:
	push	%rbp
.LCFI0:
	mov	%rbp, %rsp
.LCFI1:
	mov	DWORD PTR [%rbp-20], %edi
	mov	DWORD PTR [%rbp-24], %esi
	mov	DWORD PTR [%rbp-28], %edx
	mov	%eax, DWORD PTR [%rbp-20]
	add	%eax, 2
	mov	DWORD PTR [%rbp-16], %eax
	mov	%eax, DWORD PTR [%rbp-24]
	add	%eax, 3
	mov	DWORD PTR [%rbp-12], %eax
	mov	%eax, DWORD PTR [%rbp-28]
	add	%eax, 4
	mov	DWORD PTR [%rbp-8], %eax
	mov	%eax, DWORD PTR [%rbp-12]
	add	%eax, DWORD PTR [%rbp-16]
	add	%eax, DWORD PTR [%rbp-8]
	mov	DWORD PTR [%rbp-4], %eax
	mov	%eax, DWORD PTR [%rbp-16]
	imul	%eax, DWORD PTR [%rbp-12]
	imul	%eax, DWORD PTR [%rbp-8]
	add	%eax, DWORD PTR [%rbp-4]
	leave
	ret
.LFE2:
	.size	foobar, .-foobar
.globl main
	.type	main, @function
main:
.LFB3:
	push	%rbp
.LCFI2:
	mov	%rbp, %rsp
.LCFI3:
	mov	%edx, 99
	mov	%esi, 88
	mov	%edi, 77
	call	foobar
	leave
	ret

 ebp : 扩展基址指针寄存器(extended base pointer) 其内存放一个指针,该指针指向系统栈最上面一个栈帧的底部。(rbp  64bit  作用同 ebp )

64bit 参数传递

%rdi%rsi%rdx%r10%r8%r9
参数一参数二参数三参数四参数五参数六
main:
.LFB3:
	push	%rbp
.LCFI2:
	mov	%rbp, %rsp
.LCFI3:
	mov	%edx, 99
	mov	%esi, 88
	mov	%edi, 77
	call	foobar
	leave
	ret

所以这里 foobar 三个参数 在 main 调用 分别对应

return foobar(77, 88, 99);

77->rdi
88->rsi
99->rdx

下面在来看看 foobar 函数:

foobar:
.LFB2:
	push	%rbp
.LCFI0:
	mov	%rbp, %rsp
.LCFI1:
	mov	DWORD PTR [%rbp-20], %edi
	mov	DWORD PTR [%rbp-24], %esi
	mov	DWORD PTR [%rbp-28], %edx
	mov	%eax, DWORD PTR [%rbp-20]
	add	%eax, 2
	mov	DWORD PTR [%rbp-16], %eax
	mov	%eax, DWORD PTR [%rbp-24]
	add	%eax, 3
	mov	DWORD PTR [%rbp-12], %eax
	mov	%eax, DWORD PTR [%rbp-28]
	add	%eax, 4
	mov	DWORD PTR [%rbp-8], %eax
	mov	%eax, DWORD PTR [%rbp-12]
	add	%eax, DWORD PTR [%rbp-16]
	add	%eax, DWORD PTR [%rbp-8]
	mov	DWORD PTR [%rbp-4], %eax
	mov	%eax, DWORD PTR [%rbp-16]
	imul	%eax, DWORD PTR [%rbp-12]
	imul	%eax, DWORD PTR [%rbp-8]
	add	%eax, DWORD PTR [%rbp-4]
	leave
	ret

152335_0p3S_98920.png

前面 16 字节 主要用来在计算过程中做一些临时的存储. 对着代码就比较容易理解了

155855_LNSG_98920.png

其他的就不具体多说了。

 

转载于:https://my.oschina.net/tsh/blog/1475487

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值