先上代码:
#include "pch.h"
#include <iostream>
#include<vector>
#include<list>
#include<map>
using namespace std;
struct MyVector {
struct MyVector* pSelf;
int* pDataStart;
int* pDataEnd;
int* pBufEnd;
};
struct MyNode {
struct MyNode* pNext;
struct MyNode* pPrev;
int nData;
};
struct MyList {
struct MyList* pSelf;
struct MyNode* pRoot;
int nNodeCount;
};
void testVector() {
vector<int>vecObj;
vecObj.push_back(1);
vecObj.push_back(2);
vecObj.push_back(3);
vecObj.pop_back();
vecObj.push_back(4);
vecObj.push_back(5);
vecObj.push_back(6);
vecObj.push_back(7);
for (size_t i = 0; i < vecObj.size(); i++) {
printf("vecObj[%d]=%d", i, vecObj[i]);
}
vector<int>::iterator iter = vecObj.begin();
while (iter != vecObj.end()) {
int n = *iter;
printf("vecObj i=%d", n);
iter++;//有临时对象产生
//++iter;无临时对象产生
}
MyVector* pVector = (MyVector*) &vecObj;
int size = ((int)pVector->pDataEnd - (int)pVector->pDataStart) / sizeof(int);
for (size_t i = 0; i < size; i++) {
//pVector->pDataStart[i] = 3;
int n = pVector->pDataStart[i];
printf("元素=%d\n", n);
}
}
void testList() {
//双向循环链表,节点
list<int> listObj;
listObj.push_back(1);
listObj.push_back(2);
listObj.push_back(3);
listObj.push_back(4);
MyList* pList = (MyList*)&listObj;
int size = pList->nNodeCount;
MyNode* pNode = pList->pRoot;
while (pNode->pNext != pList->pRoot) {
pNode = pNode->pNext;
int n = pNode->nData;
printf("元素=%d\n", n);
}
}
struct MyMapNode {
struct MyMapNode* pLeft;
struct MyMapNode* pParent;
struct MyMapNode* pRight;
int unknown;
int nKey;
int nValue;
};
struct MyMap{
struct MyMap* pSelf;
struct MyMapNode* pRoot;
int nNodeCount;
};
void enumMapNode(MyMapNode* pNode, MyMapNode* pRoot) {
if (pNode == pRoot)
return;
enumMapNode(pNode->pLeft, pRoot);
printf("key=%d,value=%d\n", pNode->nKey, pNode->nValue);
enumMapNode(pNode->pRight, pRoot);
}
void testMap() {
map<int, int>mapObj;
typedef pair<int, int>Int_Pair;
mapObj.insert(Int_Pair(1, 0x11));
mapObj.insert(Int_Pair(1, 0x22));
mapObj.insert(Int_Pair(1, 0x33));
mapObj.insert(Int_Pair(1, 0x44));
mapObj.insert(Int_Pair(1, 0x55));
mapObj.insert(Int_Pair(1, 0x66));
MyMap* pMap = (MyMap*)&mapObj;
MyMapNode* pNode = pMap->pRoot->pParent;
enumMapNode(pNode, pMap->pRoot);
}
int main() {
testVector();
testList();
testMap();
getchar();
return 0;
}
******* ***********************************************************************************************
vector
找到main函数之后,这一系列操作都是常规的开辟栈帧的操作
由于main函数里面就四个函数,所以这里的反汇编代码也不多,具体每个函数是什么意思跟进去看一下就明白了
下面给自己写一下关于加标签的备注,怕以后忘记:
选中想要查看并且不清楚目的的call函数,点击enter进入jmp跳转表,如下:
一开始的时候,并不清楚这个函数代表什么意思,就选中之后enter一下:
到达跳转表之后继续enter:
一直往下会找到一个自动添加上的注释,晓得意思时候返回到jmp表:
在英文输入法的模式下,按下‘:’键,添加标签后再返回到main函数里,就添加上了标签并自动修改了函数名
进入vector里面,看一看一些关键函数:
1.构造函数:
构造函数的特点:
他有两个函数,第一个初始化为0,第二个,有初始值。
看汇编代码,参数是否用到ecx
黄色部分是push_back(1)的操作
这里黄色部分是pop_back的操作
什么是临时对象?i++就会构建临时对象,先运算后自增 但是++i就不会构建临时对象
因此这里有三个函数:size()、i++、printf()
上面,黄色部分是一个for循环,只有满足了条件之后才会跳出循环:JNB,上图黄色部分上面的JMB到lea都是循环变量的自增:
********* **********************************************************************************
这里是迭代器对象的构造,典型的构造函数,有用到ecx,lea,call什么叫做迭代器对象?迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。大概就理解成从begin()到end()吧!
上图,两个函数,begin()和end()
运算符重载返回的值是一个布尔值,如果布尔值为false就结束循环
je往上看,test eax,eax eax往回追溯,到al,在往上是一个函数的返回值,因此这里返回的必定是true or false
那么这个函数究竟是跟谁比不同,返回布尔值呢?往上看,有个edx,edx是0x1D4
0x1D4是从0x1D0来的,,1D0是从eax来的,就是end()函数,这个函数也是一个迭代器
end()迭代器,begin()迭代器都是指向的vector对象,这个vector对象是同一个对象
但是end()迭代器的第二个字段指向的是begin()迭代器的第一个字段
即:后获取的迭代器的中间字段存储的是上一个获取的迭代器的地址(这里还没有跟进去看,所以没上图,后期补!)