背景:定位一些Crash崩溃时,由于缺少更多信息,可能需要从反汇编的静态代码段推测对应的C++代码,并结合寄存器值分析出具体原因。对于Release发布版,由于编译器的强行函数内联和生成指令优化,会出现反汇编代码和C++源码区别较大,加大我们从汇编代码反推C++难度,一但我们分析清楚优化点,可以很欣赏编译器优化之美。
本文是从ARM64平台的一次crash反汇编分析经历出发,发现编译器能在我们根本没写判断的情况下,自动增加条件判断,启用128位寄存器的NENO指令进行加速,这是我以前在PC平台从未见过的优化,惊叹之佘,忍不住在我手上仅有的多平台做进一步分析,写一段简单C++代码,同样的代码在Windows下用VS2019选X64,X86,MAC家的XCode C++ 64位 ,Android Studio的ARM64,这四个平台都用Release版本生成,然后用IDA进行静态分析对比,体验一下编译器的强大之处。
我简单写了一个测试样例,C++字符串,加上测试,全部只有60行。为了简化,没有专门的内存分配器,也没有引入一些迭代器,萃取机制,为了简化也有直接用strlen()取长度等不符合模板泛型编程等,但这些不影响分析。无论在那个平台下,都用同样的代码,都会重点分析TestMyString()函数和生成以及差别最大的TCopy()函数。
template<typename T>
T* TCopy(const T* pStart, const T* pFinish, T* pDst)
{
for (; pStart != pFinish; ++pDst, ++pStart)
{
*pDst = *pStart;
}
return pDst;
};
template<typename T>
struct TString
{
~TString()
{
if (_StartPtr) delete _StartPtr;
}
TString(const T* pcStr)
{
Assign(pcStr, pcStr + strlen(pcStr));
}
TString<T>& operator = (const TString<T>& rkRight)
{
if (&rkRight != this)
{
Assign(rkRight._StartPtr, rkRight._FinishPtr);
}
return *this;
}
void Assign(const T* pStart, const T* pFinish)
{
if (pStart =