c++ ,asm一些无聊的事情

3 篇文章 0 订阅

参考,http://blog.csdn.net/feixiaoxing/article/details/6751534


1.编译器在翻译一些语句是,和想象的不同

    char a[]="hello";
00E535B8  mov         eax,dword ptr [string "hello" (0E55868h)] 
00E535BD  mov         dword ptr [ebp-10h],eax 
00E535C0  mov         cx,word ptr ds:[0E5586Ch] 
00E535C7  mov         word ptr [ebp-0Ch],cx 
    char b[]="12345678";
00E535CB  mov         eax,dword ptr [string "12345678901" (0E55874h)] 
00E535D0  mov         dword ptr [ebp-24h],eax 
00E535D3  mov         ecx,dword ptr ds:[0E55878h] 
00E535D9  mov         dword ptr [ebp-20h],ecx 
00E535DC  mov         dl,byte ptr ds:[0E5587Ch] 
00E535E2  mov         byte ptr [ebp-1Ch],dl 
    char d[]="123456789012345678901234567890";
00E535E5  mov         ecx,7 
00E535EA  mov         esi,offset string "123456789012345678901234567890" (0E55AC8h) 
00E535EF  lea         edi,[ebp-4Ch] 
00E535F2  rep movs    dword ptr es:[edi],dword ptr [esi] 
00E535F4  movs        word ptr es:[edi],word ptr [esi] 
00E535F6  movs        byte ptr es:[edi],byte ptr [esi] 

第一句,6字节,拆分为,一个dword,一个word;

第二句,9字节,拆分为,两个dword,一个byte;

第三句,31字节,拆分为,7个dword,一个word,一个byte

也就是能凑成dword的,都用dword操作。


2.用非法指针调用成员函数

#include <iostream>

using namespace std;

class Apple
{
public:
	void print()
	{
		cout<<"NULL->print()"<<endl;
		return;
	}
};
void test2()
{
	((Apple*)0)->print();
}

int main()
{
	test2();
	return 0;
}

上面的代码是可以正常运行的,输出
NULL->print()


3.函数内部

debug编译运行的代码中,函数开头,总会有这样的汇编片段

void test()
{
00E014C0  push        ebp    
00E014C1  mov         ebp,esp 
00E014C3  sub         esp,110h
00E014C9  push        ebx  
00E014CA  push        esi  
00E014CB  push        edi  
00E014CC  lea         edi,[ebp-110h] 
00E014D2  mov         ecx,44h 
00E014D7  mov         eax,0CCCCCCCCh 
00E014DC  rep stos    dword ptr es:[edi] 
...
这两句,

sub  esp,110h

lea  edi,[ebp-110h]

中的数字一般相同。

如果我没猜错的话,应该是为了使未初始化的栈内存空间填充为OxCCCC。

另外,110h=44h*4,可能是函数局部变量空间的大小,也就是该函数在栈上所占的空间(例子中还有16字节用来保存寄存器,开始4字节,结尾12字节,中间夹着110字节)。

函数结束,汇编片段

}
00AC1703  pop         edi  
00AC1704  pop         esi  
00AC1705  pop         ebx  
00AC1706  mov         esp,ebp 
00AC1708  pop         ebp  
00AC1709  ret        

4.函数调用

void test5(int a, int b)
{
	int c=a+b;
}
int test6(int a, int b)
{
	int c=a+b;
	return c;
}
调用片段

	test5(1,2);
00191BD8  push        2    
00191BDA  push        1    
00191BDC  call        test5 (191271h) 
00191BE1  add         esp,8 
	a=test6(3,4);
00191BE4  push        4    
00191BE6  push        3    
00191BE8  call        test6 (19126Ch) 
00191BED  add         esp,8 
00191BF0  mov         dword ptr [a],eax 
test6的完整翻译

int test6(int a, int b)
{
00191750  push        ebp  
00191751  mov         ebp,esp 
00191753  sub         esp,0CCh 
00191759  push        ebx  
0019175A  push        esi  
0019175B  push        edi  
0019175C  lea         edi,[ebp-0CCh] 
00191762  mov         ecx,33h 
00191767  mov         eax,0CCCCCCCCh 
0019176C  rep stos    dword ptr es:[edi] 
	int c=a+b;
0019176E  mov         eax,dword ptr [a] 
00191771  add         eax,dword ptr [b] 
00191774  mov         dword ptr [c],eax 
	return c;
00191777  mov         eax,dword ptr [c] 
}

5.未完待续



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值