new 的反汇编解释

int *p=new int [10];
00408170   push        ebp
00408171   mov         ebp,esp
00408173   push        ecx
00408174   push        1
00408176   mov         eax,dword ptr [cb]
00408179   push        eax
0040817A   call        _nh_malloc (004084e0)
0040817F   add         esp,8
00408182   mov         dword ptr [res],eax
00408185   mov         eax,dword ptr [res]
00408188   mov         esp,ebp
0040818A   pop         ebp
0040818B   ret
//谁能给具体解释下这段反汇编
00401122 89 45 FC             mov         dword ptr [res],eax//把_nh_malloc的返回值给[res]
00401125 8B 45 FC             mov         eax,dword ptr [res]//返回申请内存的指针

不太了解[res]是什么?
还有eax经过这两句不是没有变化么。。
就像r=ax;
ax=r;//这句还需要吗
 
 
3:        int *p=new int [10];
004010E8 6A 28                push        28h//内存的大小10*4
004010EA E8 21 00 00 00       call        operator new (00401110)
004010EF 83 C4 04             搜索add         esp,4

00401110 55                   push        ebp
00401111 8B EC                mov         ebp,esp
00401113 51                   push        ecx
00401114 6A 01                push        1//_nh_malloc参数2
00401116 8B 45 08             mov         eax,dword ptr [cb]
00401119 50                   push        eax//_nh_malloc参数1
0040111A E8 E1 3B 00 00       call        _nh_malloc (00404d00)//调用_nh_malloc申请内存
0040111F 83 C4 08             add         esp,8
00401122 89 45 FC             mov         dword ptr [res],eax//把_nh_malloc的返回值给[res]
00401125 8B 45 FC             mov         eax,dword ptr [res]//返回申请内存的指针
00401128 8B E5                mov         esp,ebp
0040112A 5D                   pop         ebp
0040112B C3                   ret//返回

调用过程可以看成这样:
new[4*10]->_nh_malloc(40, 1)->返回申请的指针

res这个是VC6.0反汇编后给出的变量名,其实它是一个局部变量
push        ecx  //这句就是申请res的内存的 相当sub esp, 4

00401122 89 45 FC             mov         dword ptr [res],eax//把_nh_malloc的返回值给[res]
00401125 8B 45 FC             mov         eax,dword ptr [res]//返回申请内存的指针
为什么会产生产生上面的2句代码?
因为这个是调试模式的编译,代码没有优化,所以才会产生这样的问题
<mov         dword ptr [res],eax> 等于 <res = _nh_malloc(...)>
<mov         eax,dword ptr [res] 等于 <return res;> >void TestClass( void )
99: {
004011C0 push ebp
004011C1 mov ebp,esp
004011C3 sub esp,5Ch
004011C6 push ebx
004011C7 push esi
004011C8 push edi
004011C9 lea edi,[ebp-5Ch]
004011CC mov ecx,17h
004011D1 mov eax,0CCCCCCCCh
004011D6 rep stos dword ptr [edi]
100: Assembly as( 0 ); // Assembly为12字节
004011D8 push 0
004011DA lea ecx,[ebp-0Ch]
004011DD call @ILT+30(Assembly::Assembly) (00401023)
101: char *p = new char[5];004011E2 push 5
004011E4 call operator new (00403840)
004011E9 add esp,4
004011EC mov dword ptr [ebp-18h],eax
004011EF mov eax,dword ptr [ebp-18h]
004011F2 mov dword ptr [ebp-10h],eax
102: const char *pTitle = "notificaiton";
004011F5 mov dword ptr [ebp-14h],offset string "notificaiton" (00429120)
上面红色的为源代码,源代码下面的就是vc6汇编的结果。有几处搞不清,请高手指点迷津:
1) add esp,4 :为什么要将栈指针加4,就算是吧new之后返回的指针值压入栈中,也不是将esp加4,而应该减4.
2) add esp,4 之后的那三句到底在干什么?
3) 为什么在这里看到汇编这样调用new操作符,当我在代码中嵌入这样的汇编时,
__asm
{
push 5
call operator new
}
它就告诉我
D:\Study\C++\TestAssembly\main.cpp(107) : error C2414: illegal number of operands
D:\Study\C++\TestAssembly\main.cpp(107) : error C2400: inline assembler syntax error in 'first operand'; found 'bad token'
D:\Study\C++\TestAssembly\main.cpp(108) : error C2400: inline assembler syntax error in 'opcode'; found 'bad token'
D:\Study\C++\TestAssembly\main.cpp(108) : warning C4405: 'mov' : identifier is reserved word
3)同样的语句mov dword ptr [ebp-14h],offset string "notificaiton"在上面的代码里,我把这句写在自己的内嵌汇编代码中就编译不过呢?
各位路过的大虾们,我的这些CC的问题让大家见笑了,不过还是恳请赐教!函数调用之前与调用之后堆栈指针的值(esp)必须不变。在call operator new之前不是push 5了吗?5是一个int,大小为4字节,因此esp减了4(注意堆栈是倒增长的)。call完了operator new,必须把esp加上4以保持堆栈平衡。
函数的返回值一般放在eax中,因此,add esp 4之后的3句是把new来的指针放到p变量中去。
嵌入汇编有自己的语法,跟纯汇编略有区别,具体请看msdn。call operator new (00403840)
这里 operator new实际上给的是debug信息,并不是真正的函数名004011EC mov dword ptr [ebp-18h],eax
004011EF mov eax,dword ptr [ebp-18h]
004011F2 mov dword ptr [ebp-10h],eax
这三句相当于
1。函数返回的结果生成一个临时变量
2。将临时变量拷贝到目标变量中
比较符合C++的语义,当然C++是允许对这样的语义进行优化的。

operator new并不是最终可以导出的符号,而且C++对名字作适当的调整,而汇编代码并不接受C++的语法,所以很难通过call调用C++的函数,
lz你看到的call operator new 只是编译器根据机器指令计算出call的目标位置,锁定该函数的原始名字,便于调试罢了
 

转载于:https://my.oschina.net/u/1398304/blog/283538

IDA反汇编工具是一款十分强大的反汇编工具,不仅支持各种处理器架构,还提供了丰富的反汇编和调试功能。对于51系列单片机的反汇编,IDA也是支持的。以下是IDA反汇编工具51系列使用说明: 1. 安装IDA:首先需要下载并安装IDA软件,建议选择官方网站进行下载,确保软件的安全可靠。 2. 选择芯片型号:打开IDA软件后,选择File -> New,会弹出一个窗口,选择51系列单片机所对应的芯片型号,然后点击OK。 3. 导入Hex文件:在弹出的新窗口中,选择要反汇编的Hex文件,然后选择芯片的熔丝位设置,点击OK。此时IDA会将Hex文件反汇编为汇编代码。 4. 查看反汇编代码:在左侧的窗口中选择需要查看的函数或代码段,可以查看该部分的反汇编代码。可以通过右键菜单选择反汇编风格、字体大小等选项进行设置。 5. 修改反汇编代码:可以通过双击汇编代码进行修改,修改后可以选择保存或者撤销修改。需要注意的是,IDA只是反汇编工具,修改汇编代码并不能直接影响Hex文件。 6. 调试程序:可以通过IDA内置的调试器进行程序调试,选择Debugger->Process Options进行设置,然后选择Debugger->Run进行启动调试。 7. 插件扩展功能:IDA支持插件扩展功能,可以通过安装插件来增加IDA的功能。可以在IDA的官网上下载和安装插件。 以上是IDA反汇编工具51系列使用说明,希望能对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值