关于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
- 关于AT&T汇编和c语言的相互调用的分析
- C/C++与汇编的函数相互调用分析
- C/C++与汇编的函数相互调用分析
- Linux下NASM汇编函数和C语言函数相互调用的方法
- AT&T和Intel汇编的语法
- c语言和c++的相互调用
- AT&T 汇编调用C库函数
- 一个操作系统的实现(12)-汇编和C相互调用
- 转intel汇编和AT&T汇编的区别
- intel汇编 和 AT&T汇编 的区别
- C于汇编函数的相互调用
- 汇编与c的相互调用
- 汇编和C相互调用
- AT&T的汇编世界
- C语言函数和汇编函数相互调用(转)
- C语言函数和汇编函数相互调用
- 一段C语言和汇编的对应分析,揭示函数调用的本质
- c 语言调用汇编堆栈的详细分析
- HMC5883L 磁力计校准
- Python 包管理工具解惑
- Java线程详解
- 数据库事务隔离级别
- 磁力计的基本工作原理
- 关于AT&T汇编和c语言的相互调用的分析
- select, iocp, epoll,kqueue及各种I/O复用机制
- easeljs web开发围住神经小猫咪【一】
- cocostudio scrollview裁切bug
- Android多机适配
- html 等待界面
- Java多线程操作
- 操作系统之分页式内存管理1
- Web前端引路灯