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

来源:互联网 发布:文登考研怎么样 知乎 编辑:程序博客网 时间:2024/05/02 02:32

这方面很多人写了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_endprocLFE6:        .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 %ebpmovl %esp,%ebpmovl 8(%ebp),%eaximull %eax,%eaxmovl %ebp,%esppopl %ebpret
这里会说到c样式的函数调用,即参数传递通过栈。

看看示意图

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

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

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

如下:

main.o:     file format pe-i386Disassembly 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                   nopDisassembly 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 %ebpmovl %esp,%ebp<span style="color:#ff0000;">movl 8(%ebp),%eax      i的值movl 12(%ebp),%ecx     j的值</span>addl %ecx,%eaxmovl %ebp,%esppopl %ebpret


将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


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



0 0
原创粉丝点击