您的位置:首页 > 编程语言 > C语言/C++

关于AT&T汇编和c语言的相互调用的分析

2015-03-10 10:26 573 查看
这方面很多人写了blog,这次我也是学习,从objdump等工具分析。

------------------------c中调用汇编-------------------------------

首先给出c文件

#include<stdio.h>

int main()
{
int j;
j=add(3);
printf("add(3) is %d\n",j);
}


add是用汇编完成的,看看c如何调用这个函数,当然这里的add不仅仅可以用汇编写,其他都可以,只是函数的一个入口地址。

利用gcc -S main.c -o main.s 看看汇编代码

$ cat main.s
.file   "main.c"
.def    ___main;        .scl    2;      .type   32;     .endef
.section .rdata,"dr"
LC0:
.ascii "add(3) is %d\12\0"
.text
.globl  _main
.def    _main;  .scl    2;      .type   32;     .endef
_main:
LFB6:
.cfi_startproc
pushl   %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl    %esp, %ebp
.cfi_def_cfa_register 5
andl    $-16, %esp
subl    $32, %esp
call    ___main
movl    $3, (%esp)
<span style="color:#ff0000;"> call    _add</span>
movl    %eax, 28(%esp)
movl    28(%esp), %eax
movl    %eax, 4(%esp)
movl    $LC0, (%esp)
<span style="color:#ff0000;">call    _printf</span>
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE6:
.ident  "GCC: (GNU) 4.8.1"
.def    _add;   .scl    2;      .type   32;     .endef
.def    _printf;        .scl    2;      .type   32;     .endef


从中可以看到两次调用(红色),也就是add的入口标签为_add.

下面为add的汇编函数

.globl _add
.section .text
_add:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
imull %eax,%eax
movl %ebp,%esp
popl %ebp
ret
这里会说到c样式的函数调用,即参数传递通过栈。

看看示意图



此汇编的前提就是在call _add 之前就要将要传递的时放到stack中。

为此将main,c add.s 汇编成 mian.o

gcc -o main.o main.c add.s

如下:

main.o:     file format pe-i386

Disassembly of section .text:

00000000 <_main>:
<span style="color:#009900;"> 0:	55                   	push   %ebp    这里是为了对齐暂时不研究
1:	89 e5                	mov    %esp,%ebp
3:	83 e4 f0             	and    $0xfffffff0,%esp
6:	83 ec 20             	sub    $0x20,%esp</span>
<span style="color:#3333ff;"> 9:	e8 00 00 00 00       	call   e <_main+0xe> 这是在调用函数之前完成的事情
e:	c7 04 24 03 00 00 00 	movl   $0x3,(%esp) 将立即数3压入栈中,</span>
15:	e8 1a 00 00 00       	<span style="color:#ff0000;">call   34 <_add>  调用add函数</span>
1a:	89 44 24 1c          	mov    %eax,0x1c(%esp)
1e:	8b 44 24 1c          	mov    0x1c(%esp),%eax
22:	89 44 24 04          	mov    %eax,0x4(%esp)
26:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
2d:	e8 00 00 00 00       	call   32 <_main+0x32>
32:	c9                   	leave
33:	c3                   	ret

00000034 <_add>:
34:	55                   	push   %ebp
35:	89 e5                	mov    %esp,%ebp
37:	8b 45 08             	mov    0x8(%ebp),%eax
3a:	0f af c0             	imul   %eax,%eax
3d:	89 ec                	mov    %ebp,%esp
3f:	5d                   	pop    %ebp
40:	c3                   	ret
41:	90                   	nop
42:	90                   	nop
43:	90                   	nop

Disassembly of section .rdata:

00000000 <.rdata>:
0:	61                   	popa
1:	64 64 28 33          	fs sub %dh,%fs:(%ebx)
5:	29 20                	sub    %esp,(%eax)
7:	69 73 20 25 64 0a 00 	imul   $0xa6425,0x20(%ebx),%esi
...

Disassembly of section .rdata$zzz:

00000000 <.rdata$zzz>:
0:	47                   	inc    %edi
1:	43                   	inc    %ebx
2:	43                   	inc    %ebx
3:	3a 20                	cmp    (%eax),%ah
5:	28 47 4e             	sub    %al,0x4e(%edi)
8:	55                   	push   %ebp
9:	29 20                	sub    %esp,(%eax)
b:	34 2e                	xor    $0x2e,%al
d:	38 2e                	cmp    %ch,(%esi)
f:	31 00                	xor    %eax,(%eax)
11:	00 00                	add    %al,(%eax)
...

Disassembly of section .eh_frame:

00000000 <.eh_frame>:
0:	14 00                	adc    $0x0,%al
2:	00 00                	add    %al,(%eax)
4:	00 00                	add    %al,(%eax)
6:	00 00                	add    %al,(%eax)
8:	01 7a 52             	add    %edi,0x52(%edx)
b:	00 01                	add    %al,(%ecx)
d:	7c 08                	jl     17 <.eh_frame+0x17>
f:	01 1b                	add    %ebx,(%ebx)
11:	0c 04                	or     $0x4,%al
13:	04 88                	add    $0x88,%al
15:	01 00                	add    %eax,(%eax)
17:	00 1c 00             	add    %bl,(%eax,%eax,1)
1a:	00 00                	add    %al,(%eax)
1c:	1c 00                	sbb    $0x0,%al
1e:	00 00                	add    %al,(%eax)
20:	04 00                	add    $0x0,%al
22:	00 00                	add    %al,(%eax)
24:	34 00                	xor    $0x0,%al
26:	00 00                	add    %al,(%eax)
28:	00 41 0e             	add    %al,0xe(%ecx)
2b:	08 85 02 42 0d 05    	or     %al,0x50d4202(%ebp)
31:	70 c5                	jo     fffffff8 <_add+0xffffffc4>
33:	0c 04                	or     $0x4,%al
35:	04 00                	add    $0x0,%al
...


分析如上。

------------------------------

几个问题:

1:将汇编中_add换成add

无法识别

--------------------两个参数的传递---------------------------------------------------------------------------------------

将上面稍稍修改一下

#include<stdio.h>
int main()
{
int result;
int i,j;
i=2;j=3;
result=add(i,j);
printf("add(3) is %d\n",j);
}


add为

.globl _add
.section .text
_add:
pushl %ebp
movl %esp,%ebp

<span style="color:#ff0000;">movl 8(%ebp),%eax      i的值
movl 12(%ebp),%ecx     j的值</span>
addl %ecx,%eax
movl %ebp,%esp
popl %ebp
ret


将main.c编译成.s文件为(部分)

_main:
LFB6:
.cfi_startproc
pushl   %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl    %esp, %ebp
.cfi_def_cfa_register 5
andl    $-16, %esp
subl    $32, %esp
call    ___main
<span style="color:#ff0000;">movl    $2, 28(%esp)
movl    $3, 24(%esp)
movl    24(%esp), %eax
movl    %eax, 4(%esp)   j的值
movl    28(%esp), %eax
movl    %eax, (%esp)    i的值</span>
call    _add
movl    %eax, 20(%esp)
movl    24(%esp), %eax
movl    %eax, 4(%esp)
movl    $LC0, (%esp)
call    _printf
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret


这里主要注意将参数压栈的顺序
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: