关于AT&T汇编和c语言的相互调用的分析
2015-03-10 10:26
573 查看
这方面很多人写了blog,这次我也是学习,从objdump等工具分析。
------------------------c中调用汇编-------------------------------
首先给出c文件
add是用汇编完成的,看看c如何调用这个函数,当然这里的add不仅仅可以用汇编写,其他都可以,只是函数的一个入口地址。
利用gcc -S main.c -o main.s 看看汇编代码
从中可以看到两次调用(红色),也就是add的入口标签为_add.
下面为add的汇编函数
看看示意图
![](http://img.blog.csdn.net/20150310104917828?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDQ0MjMyOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
此汇编的前提就是在call _add 之前就要将要传递的时放到stack中。
为此将main,c add.s 汇编成 mian.o
gcc -o main.o main.c add.s
如下:
分析如上。
------------------------------
几个问题:
1:将汇编中_add换成add
无法识别
--------------------两个参数的传递---------------------------------------------------------------------------------------
将上面稍稍修改一下
add为
将main.c编译成.s文件为(部分)
这里主要注意将参数压栈的顺序
------------------------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
这里主要注意将参数压栈的顺序
相关文章推荐
- 关于C语言和汇编语言相互嵌套调用
- ARM汇编 C语言 C++ 相互调用 <此方法在armv8 测试成功 !>
- 关于C语言和汇编语言相互嵌套调用
- C/C++与汇编的函数相互调用分析
- linux下的C语言开发(AT&T 汇编语言) 04
- 关于AT&T 汇编:64 位与32 位的区别
- C语言与汇编语言相互调用
- 关于AT&T 汇编:64 位之于32 位的变化
- 关于在 KEIL C51 中嵌入汇编以及C51与A51间的相互调用
- C语言与汇编语言的相互调用
- ARM汇编 C语言 C++ 相互调用
- Linux AT&T汇编 系统调用
- 转几篇关于linux下AT&T汇编的帖子
- AT&T学习笔记汇编之内联c语言
- C语言extern引用AT&T汇编中的变量,任意转换类型
- linux下的C语言开发(AT&T 汇编语言)
- AT&T 汇编调用C库函数
- 关于在 KEIL C51 中嵌入汇编以及C51与A51间的相互调用
- 关于一个工程中多个文件的相互调用的学习笔记(C语言)
- linux下的C语言开发(AT&T 汇编语言)