日期:2014-05-16 浏览次数:20935 次
在C语言中,基本的数据类型无非是char, short, int,long, float, double及相应的指针。那么它们在内存里是怎样存放的,在汇编指令里显示怎么样的特征呢?在这里就分别来探究一下char, short, int, long, float, double的特征。
先用一个例子来看一下char的特征:
#include <stdio.h> int main() { char c1 = 'a'; char c2 = 'b'; char c3 = 'c'; printf( "addresses of c1 to c3 are (%x, %x, %x)\n", &c1, &c2, &c3 ); char* p = &c1; *p++; p = &c2; (*p) += 2; p = &c3; (*p) += 3; printf( "address and value of p is ( %x, %c )\n", &p, *p ); return 0; }
编译它:
g++ -o xuzhina_dump_c5_s1 xuzhina_dump_c5_s1.cpp
用gdb打开它,反汇编这个函数:
(gdb) disassemble main Dump of assembler code for function main: 0x08048570 <+0>: push %ebp 0x08048571 <+1>: mov %esp,%ebp 0x08048573 <+3>: and $0xfffffff0,%esp 0x08048576 <+6>: sub $0x20,%esp 0x08048579 <+9>: movb $0x61,0x1f(%esp) 0x0804857e <+14>: movb $0x62,0x1e(%esp) 0x08048583 <+19>: movb $0x63,0x1d(%esp) 0x08048588 <+24>: lea 0x1d(%esp),%eax 0x0804858c <+28>: mov %eax,0xc(%esp) 0x08048590 <+32>: lea 0x1e(%esp),%eax 0x08048594 <+36>: mov %eax,0x8(%esp) 0x08048598 <+40>: lea 0x1f(%esp),%eax 0x0804859c <+44>: mov %eax,0x4(%esp) 0x080485a0 <+48>: movl $0x80486c4,(%esp) 0x080485a7 <+55>: call 0x8048440 <printf@plt> 0x080485ac <+60>: lea 0x1f(%esp),%eax 0x080485b0 <+64>: mov %eax,0x18(%esp) 0x080485b4 <+68>: mov 0x18(%esp),%eax 0x080485b8 <+72>: add $0x1,%eax 0x080485bb <+75>: mov %eax,0x18(%esp) 0x080485bf <+79>: lea 0x1e(%esp),%eax 0x080485c3 <+83>: mov %eax,0x18(%esp) 0x080485c7 <+87>: mov 0x18(%esp),%eax 0x080485cb <+91>: mov 0x18(%esp),%edx 0x080485cf <+95>: movzbl (%edx),%edx 0x080485d2 <+98>: add $0x2,%edx 0x080485d5 <+101>: mov %dl,(%eax) 0x080485d7 <+103>: lea 0x1d(%esp),%eax 0x080485db <+107>: mov %eax,0x18(%esp) 0x080485df <+111>: mov 0x18(%esp),%eax 0x080485e3 <+115>: mov 0x18(%esp),%edx 0x080485e7 <+119>: movzbl (%edx),%edx 0x080485ea <+122>: add $0x3,%edx 0x080485ed <+125>: mov %dl,(%eax) 0x080485ef <+127>: mov 0x18(%esp),%eax 0x080485f3 <+131>: movzbl (%eax),%eax 0x080485f6 <+134>: movsbl %al,%eax 0x080485f9 <+137>: mov %eax,0x8(%esp) 0x080485fd <+141>: lea 0x18(%esp),%eax 0x08048601 <+145>: mov %eax,0x4(%esp) 0x08048605 <+149>: movl $0x80486ec,(%esp) 0x0804860c <+156>: call 0x8048440 <printf@plt> 0x08048611 <+161>: mov $0x0,%eax 0x08048616 <+166>: jmp 0x8048620 <main+176> 0x08048618 <+168>: mov %eax,(%esp) 0x0804861b <+171>: call 0x8048460 <_Unwind_Resume@plt> 0x08048620 <+176>: leave 0x08048621 <+177>: ret End of assembler dump.
在第一次 printf的调用后打断点,即:
0x080485ac <+60>: lea 0x1f(%esp),%eax
然后运行一下,看程序的输出:
(gdb) tbreak *0x080485ac Temporary breakpoint 1 at 0x80485ac (gdb) r Starting program: /home/buckxu/work/5/1/xuzhina_dump_c5_s1 addresses of c1 to c3 are (bffff47f, bffff47e, bffff47d) Temporary breakpoint 1, 0x080485ac in main () (gdb) i r ebp esp ebp 0xbffff488 0xbffff488 esp 0xbffff460 0xbffff460 (gdb