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

这方面很多人写了blog,这次我也是学习,从objdump等工具分析。

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

首先给出c文件

#include

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)
        call    _add
        movl    %eax, 28(%esp)
        movl    28(%esp), %eax
        movl    %eax, 4(%esp)
        movl    $LC0, (%esp)
        call    _printf
        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样式的函数调用,即参数传递通过栈。

看看示意图

关于AT&T汇编和c语言的相互调用的分析_第1张图片

此汇编的前提就是在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>:
   0:	55                   	push   %ebp    这里是为了对齐暂时不研究
   1:	89 e5                	mov    %esp,%ebp
   3:	83 e4 f0             	and    $0xfffffff0,%esp
   6:	83 ec 20             	sub    $0x20,%esp
   9:	e8 00 00 00 00       	call   e <_main+0xe> 这是在调用函数之前完成的事情
   e:	c7 04 24 03 00 00 00 	movl   $0x3,(%esp) 将立即数3压入栈中,
  15:	e8 1a 00 00 00       	call   34 <_add>  调用add函数
  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
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
	
	movl 8(%ebp),%eax      i的值
	movl 12(%ebp),%ecx     j的值
	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
        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的值
        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


这里主要注意将参数压栈的顺序



你可能感兴趣的:(c/c++,AT&T汇编,链接,ATT汇编)