《coredump问题原理探究》Linux x86版7.10节set相关的iterator对象

原创 2015年11月20日 23:48:11

看一下set的iterator.由于map和set的相似性,只要看set就可以了.

1 #include <set>
  2 
  3 void init( std::set<int>& set )
  4 {
  5     for ( int i = 0; i < 0x10; i++ )
  6     {
  7         set.insert( i );
  8     }
  9 }
 10 
 11 int getSum( std::set<int>& set )
 12 {
 13     std::set<int>::iterator iter;
 14     int result = 0;
 15 
 16     for ( iter = set.begin(); iter != set.end(); iter++ )
 17     {
 18         result += *iter;
 19     }
 20 
 21     return result;
 22 }
 23 
 24 int main()
 25 {
 26     std::set<int> set;
 27     init( set );
 28 
 29     return getSum( set );
 30 }

同样是看一下getSum的汇编:

(gdb) disassemble getSum
Dump of assembler code for function _Z6getSumRSt3setIiSt4lessIiESaIiEE:
   0x080487a7 <+0>:	push   %ebp
   0x080487a8 <+1>:	mov    %esp,%ebp
   0x080487aa <+3>:	sub    $0x38,%esp
   0x080487ad <+6>:	lea    -0x18(%ebp),%eax
   0x080487b0 <+9>:	mov    %eax,(%esp)
   0x080487b3 <+12>:	call   0x8048914 <_ZNSt23_Rb_tree_const_iteratorIiEC2Ev>
   0x080487b8 <+17>:	movl   $0x0,-0xc(%ebp)
   0x080487bf <+24>:	lea    -0x1c(%ebp),%eax
   0x080487c2 <+27>:	mov    0x8(%ebp),%edx
   0x080487c5 <+30>:	mov    %edx,0x4(%esp)
   0x080487c9 <+34>:	mov    %eax,(%esp)
   0x080487cc <+37>:	call   0x8048922 <_ZNKSt3setIiSt4lessIiESaIiEE5beginEv>
   0x080487d1 <+42>:	sub    $0x4,%esp
   0x080487d4 <+45>:	mov    -0x1c(%ebp),%eax
   0x080487d7 <+48>:	mov    %eax,-0x18(%ebp)
   0x080487da <+51>:	jmp    0x8048809 <_Z6getSumRSt3setIiSt4lessIiESaIiEE+98>
   0x080487dc <+53>:	lea    -0x18(%ebp),%eax
   0x080487df <+56>:	mov    %eax,(%esp)
   0x080487e2 <+59>:	call   0x80489c0 <_ZNKSt23_Rb_tree_const_iteratorIiEdeEv>
   0x080487e7 <+64>:	mov    (%eax),%eax
   0x080487e9 <+66>:	add    %eax,-0xc(%ebp)
   0x080487ec <+69>:	lea    -0x10(%ebp),%eax
   0x080487ef <+72>:	movl   $0x0,0x8(%esp)
   0x080487f7 <+80>:	lea    -0x18(%ebp),%edx
   0x080487fa <+83>:	mov    %edx,0x4(%esp)
   0x080487fe <+87>:	mov    %eax,(%esp)
   0x08048801 <+90>:	call   0x8048982 <_ZNSt23_Rb_tree_const_iteratorIiEppEi>
   0x08048806 <+95>:	sub    $0x4,%esp
   0x08048809 <+98>:	lea    -0x14(%ebp),%eax
   0x0804880c <+101>:	mov    0x8(%ebp),%edx
   0x0804880f <+104>:	mov    %edx,0x4(%esp)
   0x08048813 <+108>:	mov    %eax,(%esp)
   0x08048816 <+111>:	call   0x8048948 <_ZNKSt3setIiSt4lessIiESaIiEE3endEv>
   0x0804881b <+116>:	sub    $0x4,%esp
   0x0804881e <+119>:	lea    -0x14(%ebp),%eax
   0x08048821 <+122>:	mov    %eax,0x4(%esp)
   0x08048825 <+126>:	lea    -0x18(%ebp),%eax
   0x08048828 <+129>:	mov    %eax,(%esp)
   0x0804882b <+132>:	call   0x804896e <_ZNKSt23_Rb_tree_const_iteratorIiEneERKS0_>
   0x08048830 <+137>:	test   %al,%al
   0x08048832 <+139>:	jne    0x80487dc <_Z6getSumRSt3setIiSt4lessIiESaIiEE+53>
   0x08048834 <+141>:	mov    -0xc(%ebp),%eax
   0x08048837 <+144>:	leave  
   0x08048838 <+145>:	ret    
End of assembler dump.

同样可以看到set的this指针在ebp+0x8,iter的this指针在ebp-0x18

在0x08048825打断点.

看一下set的内容:

(gdb) x /x $ebp+8
0xbffff630:	0xbffff648
(gdb) x /8x 0xbffff648
0xbffff648:	0xbffff678	0x00000000	0x0804b050	0x0804b008
0xbffff658:	0x0804b170	0x00000010	0x080491f0	0x080486b0
(gdb) x /8x 0x0804b050
0x804b050:	0x00000001	0xbffff64c	0x0804b020	0x0804b0b0
0x804b060:	0x00000003	0x00000019	0x00000001	0x0804b080
(gdb) x /8x 0x0804b020
0x804b020:	0x00000001	0x0804b050	0x0804b008	0x0804b038
0x804b030:	0x00000001	0x00000019	0x00000001	0x0804b020
(gdb) x /8x 0x0804b0b0
0x804b0b0:	0x00000000	0x0804b050	0x0804b080	0x0804b110
0x804b0c0:	0x00000007	0x00000019	0x00000001	0x0804b0e0
(gdb) x /8x 0x0804b008
0x804b008:	0x00000001	0x0804b020	0x00000000	0x00000000
0x804b018:	0x00000000	0x00000019	0x00000001	0x0804b050
(gdb) x /8x 0x0804b038
0x804b038:	0x00000001	0x0804b020	0x00000000	0x00000000
0x804b048:	0x00000002	0x00000019	0x00000001	0xbffff64c
(gdb) x /8x 0x0804b080
0x804b080:	0x00000001	0x0804b0b0	0x0804b068	0x0804b098
0x804b090:	0x00000005	0x00000019	0x00000001	0x0804b080
(gdb) x /8x 0x0804b110
0x804b110:	0x00000001	0x0804b0b0	0x0804b0e0	0x0804b140
0x804b120:	0x0000000b	0x00000019	0x00000001	0x0804b140
(gdb) x /8x 0x0804b068
0x804b068:	0x00000001	0x0804b080	0x00000000	0x00000000
0x804b078:	0x00000004	0x00000019	0x00000001	0x0804b0b0
(gdb) x /8x 0x0804b098
0x804b098:	0x00000001	0x0804b080	0x00000000	0x00000000
0x804b0a8:	0x00000006	0x00000019	0x00000000	0x0804b050
(gdb) x /8x 0x0804b0e0
0x804b0e0:	0x00000000	0x0804b110	0x0804b0c8	0x0804b0f8
0x804b0f0:	0x00000009	0x00000019	0x00000001	0x0804b0e0
(gdb) x /8x 0x0804b140
0x804b140:	0x00000000	0x0804b110	0x0804b128	0x0804b158
0x804b150:	0x0000000d	0x00000019	0x00000001	0x0804b140
(gdb) x /8x 0x0804b0c8
0x804b0c8:	0x00000001	0x0804b0e0	0x00000000	0x00000000
0x804b0d8:	0x00000008	0x00000019	0x00000000	0x0804b110
(gdb) x /8x 0x0804b0f8
0x804b0f8:	0x00000001	0x0804b0e0	0x00000000	0x00000000
0x804b108:	0x0000000a	0x00000019	0x00000001	0x0804b0b0
(gdb) x /8x 0x0804b128
0x804b128:	0x00000001	0x0804b140	0x00000000	0x00000000
0x804b138:	0x0000000c	0x00000019	0x00000000	0x0804b110
(gdb) x /8x 0x0804b158
0x804b158:	0x00000001	0x0804b140	0x00000000	0x0804b170
0x804b168:	0x0000000e	0x00000019	0x00000000	0x0804b158
(gdb) x /8x 0x0804b170
0x804b170:	0x00000000	0x0804b158	0x00000000	0x00000000
0x804b180:	0x0000000f	0x00020e81	0x00000000	0x00000000

用图来表示如下:

看一下iter的变化:

(gdb) x /8x 0x0804b008
0x804b008:	0x00000001	0x0804b020	0x00000000	0x00000000
0x804b018:	0x00000000	0x00000019	0x00000001	0x0804b050
(gdb) c
Continuing.

Breakpoint 1, 0x08048825 in getSum(std::set<int, std::less<int>, std::allocator<int> >&) ()
(gdb) x /8x $ebp-0x18
0xbffff610:	0x0804b020	0xbffff64c	0x0804b008	0x00000000
0xbffff620:	0xb7ff3170	0x00000001	0xbffff678	0x08048868
(gdb) x /8x 0x0804b020
0x804b020:	0x00000001	0x0804b050	0x0804b008	0x0804b038
0x804b030:	0x00000001	0x00000019	0x00000001	0x0804b020
(gdb) c
Continuing.

Breakpoint 1, 0x08048825 in getSum(std::set<int, std::less<int>, std::allocator<int> >&) ()
(gdb) x /8x $ebp-0x18
0xbffff610:	0x0804b038	0xbffff64c	0x0804b020	0x00000001
0xbffff620:	0xb7ff3170	0x00000001	0xbffff678	0x08048868
(gdb) x /8x 0x0804b038
0x804b038:	0x00000001	0x0804b020	0x00000000	0x00000000
0x804b048:	0x00000002	0x00000019	0x00000001	0xbffff64c
(gdb) c
Continuing.

Breakpoint 1, 0x08048825 in getSum(std::set<int, std::less<int>, std::allocator<int> >&) ()
(gdb) x /8x $ebp-0x18
0xbffff610:	0x0804b050	0xbffff64c	0x0804b038	0x00000003
0xbffff620:	0xb7ff3170	0x00000001	0xbffff678	0x08048868
(gdb) x /8x 0x0804b050
0x804b050:	0x00000001	0xbffff64c	0x0804b020	0x0804b0b0
0x804b060:	0x00000003	0x00000019	0x00000001	0x0804b080
(gdb) c
Continuing.

Breakpoint 1, 0x08048825 in getSum(std::set<int, std::less<int>, std::allocator<int> >&) ()
(gdb) x /8x $ebp-0x18
0xbffff610:	0x0804b068	0xbffff64c	0x0804b050	0x00000006
0xbffff620:	0xb7ff3170	0x00000001	0xbffff678	0x08048868
(gdb) x /8x 0x0804b068
0x804b068:	0x00000001	0x0804b080	0x00000000	0x00000000
0x804b078:	0x00000004	0x00000019	0x00000001	0x0804b0b0

可以看到,set的iterator也只有一个成员_M_node,指向set的节点.而且set的iterator遍历是采用中序遍历法.

 



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

《coredump问题原理探究》Linux x86版7.8节vector相关的iterator对象

在前面看过了一个vectorcoredump的例子,接触了vector的iterator,可以知道vector的iterator只有一个成员_M_current指向vector某一个元素. 先看一个例...

《coredump问题原理探究》Linux x86版7.7节 set对象

看一下bits/stl_map和bits/stl_set可以看到map和set的定义如下: 84 template , 85 typename _Alloc =...

《coredump问题原理探究》Linux x86版7.11节string对象

在定位map coredump的那一节已经接触了string对象.在这里重温一下. 看一个例子: 1 #include 2 #include 3 4 int main() ...

《coredump问题原理探究》Linux x86版7.3节List对象

先看一下例子: 1 #include 2 3 int main() 4 { 5 std::list lst; 6 7 lst.push_back( 0x...

《coredump问题原理探究》Linux x86版7.1节vector对象

先看一下例子: 1 #include 2 3 int main() 4 { 5 std::vector vec; 6 vec.push_back( 0xff...

《coredump问题原理探究》Linux x86版7.5节 Map对象

先看一个例子:          1 #include 2 3 int main() 4 { 5 std::map iMap; 6 7 iMa...

《coredump问题原理探究》Linux x86版4.1节函数的逆向之序言

在产品的生命周期中,会遇到各种coredump,如果在调试版本出现coredump,定位它是非常简单的事情,因为从栈就可以知道是哪一行代码出现了问题。如: (gdb) bt #0 0x4365b5...

《coredump问题原理探究》Linux x86版3.6节栈布局之gcc内嵌关键字

在intel CPU平台下,可以在代码加上__attribute__((regparm(number ) ) )指定函数调用时通过寄存器eax,edx,ecx来传递参数。其中number就是指定有多少...

《coredump问题原理探究》Linux x86版6.2节C++风格数据结构内存布局之有成员变量的类

上面一节已经探究出this指针的辨别,由this指针就可以看到类的内容。在这里,就由this指针来看一下类的成员变量是如何排列。 先看一个例子 1 #include 2 class x...

《coredump问题原理探究》Linux x86版4.2节函数的逆向之顺序结构

先看一下例子: #include int main() { int a = 0, b = 0, c = 0, d = 0; scanf( "%d,%d", &a,&b )...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)