#include <iostream> #include <stdio.h>
class Base { ?? ?public: ?? ??? ?void function_1() ?? ??? ?{ ?? ??? ??? ?printf("function_1...\n"); ?? ??? ?}
?? ??? ?virtual void function_2() ?? ??? ?{ ?? ??? ??? ?printf("function_2...\n"); ?? ??? ?} };
int main(int argc, char ** argv) { ?? ?Base base;
?? ?base.function_1(); ?? ?base.function_2(); }
[xiaozhi@linux virtual]$ gdb GNU gdb (GDB) Fedora 7.7.1-21.fc20 Copyright (C) 2014 Free Software Foundation, Inc. (gdb) file r-virtual-01 Reading symbols from r-virtual-01...done. (gdb) b *main Breakpoint 1 at 0x8048640: file r-virtual-01.cpp, line 19. (gdb) r Starting program: /home/share/work/ac-code/study-c++/virtual/r-virtual-01
Breakpoint 1, main (argc=1, argv=0xbffff194) at r-virtual-01.cpp:19 19?? ?{ Missing separate debuginfos, use: debuginfo-install libgcc-4.8.3-7.fc20.i686 libstdc++-4.8.3-7.fc20.i686 (gdb) disassemble /mr main Dump of assembler code for function main(int, char**): 19?? ?{ => 0x08048640 <+0>:?? ?55?? ?push?? %ebp ?? 0x08048641 <+1>:?? ?89 e5?? ?mov??? %esp,%ebp ?? 0x08048643 <+3>:?? ?83 e4 f0?? ?and??? $0xfffffff0,%esp ?? 0x08048646 <+6>:?? ?83 ec 20?? ?sub??? $0x20,%esp
20?? ??? ?Base base; ?? 0x08048649 <+9>:?? ?8d 44 24 1c?? ?lea??? 0x1c(%esp),%eax ?? 0x0804864d <+13>:?? ?89 04 24?? ?mov??? %eax,(%esp) ?? 0x08048650 <+16>:?? ?e8 a3 00 00 00?? ?call?? 0x80486f8 <Base::Base()>
21?? ? 22?? ??? ?base.function_1(); ?? 0x08048655 <+21>:?? ?8d 44 24 1c?? ?lea??? 0x1c(%esp),%eax ?? 0x08048659 <+25>:?? ?89 04 24?? ?mov??? %eax,(%esp) ?? 0x0804865c <+28>:?? ?e8 6f 00 00 00?? ?call?? 0x80486d0 <Base::function_1()>
23?? ??? ?base.function_2(); ?? 0x08048661 <+33>:?? ?8d 44 24 1c?? ?lea??? 0x1c(%esp),%eax ?? 0x08048665 <+37>:?? ?89 04 24?? ?mov??? %eax,(%esp) ?? 0x08048668 <+40>:?? ?e8 77 00 00 00?? ?call?? 0x80486e4 <Base::function_2()>
24?? ?} ?? 0x0804866d <+45>:?? ?b8 00 00 00 00?? ?mov??? $0x0,%eax ?? 0x08048672 <+50>:?? ?c9?? ?leave ? ?? 0x08048673 <+51>:?? ?c3?? ?ret?? ?
End of assembler dump. (gdb) n 20?? ??? ?Base base; (gdb) n 22?? ??? ?base.function_1(); (gdb) n function_1... 23?? ??? ?base.function_2(); (gdb) disassemble Dump of assembler code for function main(int, char**): ?? 0x08048640 <+0>:?? ?push?? %ebp ?? 0x08048641 <+1>:?? ?mov??? %esp,%ebp ?? 0x08048643 <+3>:?? ?and??? $0xfffffff0,%esp ?? 0x08048646 <+6>:?? ?sub??? $0x20,%esp ?? 0x08048649 <+9>:?? ?lea??? 0x1c(%esp),%eax ?? 0x0804864d <+13>:?? ?mov??? %eax,(%esp) ?? 0x08048650 <+16>:?? ?call?? 0x80486f8 <Base::Base()> ?? 0x08048655 <+21>:?? ?lea??? 0x1c(%esp),%eax ?? 0x08048659 <+25>:?? ?mov??? %eax,(%esp) ?? 0x0804865c <+28>:?? ?call?? 0x80486d0 <Base::function_1()> => 0x08048661 <+33>:?? ?lea??? 0x1c(%esp),%eax ?? 0x08048665 <+37>:?? ?mov??? %eax,(%esp) ?? 0x08048668 <+40>:?? ?call?? 0x80486e4 <Base::function_2()> ?? 0x0804866d <+45>:?? ?mov??? $0x0,%eax ?? 0x08048672 <+50>:?? ?leave ? ?? 0x08048673 <+51>:?? ?ret?? ? End of assembler dump.
/* 找出虚函数地址方法一 */ (gdb) p $esp $1 = (void *) 0xbffff0d0
(gdb) p $esp+0x1c $2 = (void *) 0xbffff0ec
(gdb) p base $3 = {_vptr.Base = 0x80487c8 <vtable for Base+8>}
(gdb) x /xw 0xbffff0ec 0xbffff0ec:?? ?0x080487c8
(gdb) x /xw 0x080487c8 0x80487c8 <_ZTV4Base+8>:?? ?0x080486e4?? ?# 虚函数地址
/* 找出虚函数地址方法二 */ (gdb) p base $4 = {_vptr.Base = 0x80487c8 <vtable for Base+8>}
(gdb) i r $esp esp??????????? 0xbffff0d0?? ?0xbffff0d0
(gdb) p /x 0xbffff0d0+0x1c $5 = 0xbffff0ec
(gdb) p /x 0xbffff0ec $6 = 0xbffff0ec
(gdb) p /x *0xbffff0ec $7 = 0x80487c8
(gdb) p /x *0x80487c8 $8 = 0x80486e4?? ??? ??? ??? ??? ?# 虚函数地址
(gdb) disassemble 0x80486e4?? ??? ??? ?# 反汇编地址处代码 Dump of assembler code for function Base::function_2(): ?? 0x080486e4 <+0>:?? ?push?? %ebp ?? 0x080486e5 <+1>:?? ?mov??? %esp,%ebp ?? 0x080486e7 <+3>:?? ?sub??? $0x18,%esp ?? 0x080486ea <+6>:?? ?movl?? $0x80487b2,(%esp) ?? 0x080486f1 <+13>:?? ?call?? 0x8048520 <puts@plt> ?? 0x080486f6 <+18>:?? ?leave ? ?? 0x080486f7 <+19>:?? ?ret?? ? End of assembler dump. (gdb)
|