C语言 用汇编来看看变量和指针实现
来源:互联网 发布:黑色星期五 软件 编辑:程序博客网 时间:2024/06/13 05:35
这篇我们用汇编看看变量咋存储的,不需要知道太多汇编语句,懂了下面几条我们就可以出发了!
leal S,D //D = &S 这个指令大部分出现在要存储指针的情况
movb $0x05, %al //R[al] = 0x05
movl %eax, -4(%ebp) //mem[R[ebp] -4] = R[eax]
movl -4(%ebp), %eax //R[eax] = mem[R[ebp] -4]
movl $LC0, (%esp) //mem[R[esp]] = $LC0 (a label)
Makefile
你需要加上 -g加入调试信息
print:aa ./aaaa: aa.o gcc -g -o aa aa.o aa.o: aa.c gcc -g -c aa.c
例子一:最简单的开始
#include <stdio.h> int main() { int c=55; int a=16; }
GDB 中输入 "layout asm" 能够实时的打开汇编窗口
│0x8048387 <frame_dummy+23> je 0x8048392 <frame_dummy+34> │ │0x8048389 <frame_dummy+25> movl $0x8049524,(%esp) │ │0x8048390 <frame_dummy+32> call *%eax │ │0x8048392 <frame_dummy+34> leave │ │0x8048393 <frame_dummy+35> ret │ │0x8048394 <main> push %ebp │ │0x8048395 <main+1> mov %esp,%ebp │ │0x8048397 <main+3> sub $0x10,%esp │ │0x804839a <main+6> movl $0x37,-0x8(%ebp)//把55放到ebp值-8的地址内 │0x80483a1 <main+13> movl $0x10,-0x4(%ebp) │B+>│0x80483a8 <main+20> mov $0x0,%eax │ │0x80483ad <main+25> leave │ │0x80483ae <main+26> ret │ │0x80483af nop │ │0x80483b0 <__libc_csu_fini> push %ebp │ │0x80483b1 <__libc_csu_fini+1> mov %esp,%ebp │ │0x80483b3 <__libc_csu_fini+3> pop %ebp │ │0x80483b4 <__libc_csu_fini+4> ret │ │0x80483b5 data32 nopw %cs:0x0(%eax,%eax,1) │ │0x80483c0 <__libc_csu_init> push %ebp │ │0x80483c1 <__libc_csu_init+1> mov %esp,%ebp │ │0x80483c3 <__libc_csu_init+3> push %edi │ │0x80483c4 <__libc_csu_init+4> push %esi │ └───────────────────────────────────────────────────────────────────────────────────────────────────┘child process 26046 In: main Line: 21 PC: 0x80483a8 0xbffff2c8:6963140134513173(gdb) p $ebp$1 = (void *) 0xbffff2a8(gdb) x/10x 0xbffff2a00xbffff2a0:0x000000370x000000100xbffff3280x006c1cc60xbffff2b0:0x000000010xbffff3540xbffff35c0xb7fff3d00xbffff2c0:0x080482e00xffffffff(gdb)上面内存空间看到0x37了吗?
例子二:加入两个指针比较一下汇编结果,你可以看见存储55和16的地址偏移变了,这说明系统预留了两个指针的栈空间
int main() { int c=55; int a=16; int *pa; int *pb;// pa = &c; return 0;}
│0x8048393 <frame_dummy+35> ret │ │0x8048394 <main> push %ebp │ │0x8048395 <main+1> mov %esp,%ebp │ │0x8048397 <main+3> sub $0x10,%esp │ │0x804839a <main+6> movl $0x37,-0x10(%ebp) //和上个例子比偏移变了 │ │0x80483a1 <main+13> movl $0x10,-0xc(%ebp) │ │0x80483a8 <main+20> mov $0x0,%eax │ │0x80483ad <main+25> leave
例子三:加上 pa=&c
int main() { int c=55; int a=16; int *pa; int *pb; pa = &c; return 0;}
8048395:89 e5 mov %esp,%ebp //ebp=esp 8048397:83 ec 10 sub $0x10,%esp // esp= 0x10 804839a:c7 45 f0 37 00 00 00 movl $0x37,-0x10(%ebp) 80483a1:c7 45 f4 10 00 00 00 movl $0x10,-0xc(%ebp) //mem of (ebp-0xc) = 0x10 80483a8:8d 45 f0 lea -0x10(%ebp),%eax //eax = get addr of ebp -0x10 80483ab:89 45 f8 mov %eax,-0x8(%ebp) // mem of (ebp -0x8) = eax 80483ae:b8 00 00 00 00 mov $0x0,%eax
Breakpoint 1, main () at aa.c:9eax 0xbffff298-1073745256ecx 0xf12bb1bf-248794689edx 0x11ebx 0x836ff48613876esp 0xbffff2980xbffff298ebp 0xbffff2a80xbffff2a8esi 0x00edi 0x00eip 0x80483ae 0x80483ae <main+26>eflags 0x282[ SF IF]cs 0x73115
例子四:在以前的文章里面我们遇到了 arrary and &array居然是同一个值,这里我们看看汇编结果,他们居然用到了同样的lea指令,C编译器结果就是这儿干的!
#include <stdio.h> int main() { int c=55; int a=16; int *pa; int *pb; pa = &c; int array[5]={1,2,3,4,5}; pa = array; pa = &array; char *str="abcdefg"; pa = str; // printf("%p\n",array); return 0;}
┌───────────────────────────────────────────────────────────────────────────────────────────────────┐ │0x8048394 <main> push %ebp │ │0x8048395 <main+1> mov %esp,%ebp │ │0x8048397 <main+3> sub $0x30,%esp │ │0x804839a <main+6> movl $0x37,-0x14(%ebp) │ │0x80483a1 <main+13> movl $0x10,-0x10(%ebp) │ │0x80483a8 <main+20> lea -0x14(%ebp),%eax │ │0x80483ab <main+23> mov %eax,-0xc(%ebp) │ │0x80483ae <main+26> movl $0x1,-0x28(%ebp) │ │0x80483b5 <main+33> movl $0x2,-0x24(%ebp) │ │0x80483bc <main+40> movl $0x3,-0x20(%ebp) │ │0x80483c3 <main+47> movl $0x4,-0x1c(%ebp) │ │0x80483ca <main+54> movl $0x5,-0x18(%ebp) │ │0x80483d1 <main+61> lea -0x28(%ebp),%eax //pa = array │ │0x80483d4 <main+64> mov %eax,-0xc(%ebp) │ │0x80483d7 <main+67> lea -0x28(%ebp),%eax //pa = &array │ │0x80483da <main+70> mov %eax,-0xc(%ebp) │ │0x80483dd <main+73> movl $0x80484c4,-0x4(%ebp) //pa=str │ │0x80483e4 <main+80> mov -0x4(%ebp),%eax │ │0x80483e7 <main+83> mov %eax,-0xc(%ebp) │B+>│0x80483ea <main+86> mov $0x0,%eax │ │0x80483ef <main+91> leave │ │0x80483f0 <main+92> ret │ │0x80483f1 nop │ └───────────────────────────────────────────────────────────────────────────────────────────────────┘child process 26991 In: main Line: 15 PC: 0x80483ea (gdb) ir ebpebp 0xbffff2a80xbffff2a8(gdb) x/10x 0x80484c40x80484c4 <__dso_handle+4>:0x646362610x006766650x3b031b010x000000200x80484d4:0x000000030xffffff340x0000003c0xffffff440x80484e4:0x0000005c0xffffff9e
0 0
- C语言 用汇编来看看变量和指针实现
- 用汇编来看C语言的简单实现(转)
- 用汇编来看看inline
- C语言的变量域和指针
- 走进内存,走进汇编指令来看C/C++指针
- 用汇编的眼光看C++(之指针1)
- 用汇编的眼光看C++(之指针2)
- 用汇编的眼光看C++(之指针1)
- 用汇编的眼光看C++(之指针2)
- 用汇编的眼光看C++(之指针1)
- 用汇编的眼光看C++(之指针2)
- 用汇编的眼光看C++(之指针1)
- 用汇编的眼光看C++(之指针2)
- 用汇编的眼光看C++(之指针1)
- 用汇编的眼光看C++(之指针2)
- 用汇编的眼光看C++(之指针)
- 用汇编的眼光看C++(之指针)
- 用汇编的眼光看C/C++之深入指针
- Java中的值传递和引用传递
- html基础--标签,属性,文本格式化标签,计算机输出标签,引用和术语定义
- 南邮 OJ 1911 军训
- manifest配置权限区分大小写
- RegionServer功能职责
- C语言 用汇编来看看变量和指针实现
- (C/C++学习笔记)Copy构造函数应用场景
- 【Android杂谈】安卓开发模拟按键-坐标万能版(二)
- HDOJ 2023 求平均成绩(水)
- 动态规划 uva 1025
- css 曲线阴影
- 最近在整理数据库结构,顺带整理了一个varchar、char、nvarchar、nchar的区别
- System V IPC vs POSIX IPC
- 南邮 OJ 1912 E.V.O.L