有趣的汇编

要想深入理解C/C++,必须得了解汇编语言,由于现代编译器的强大,帮我们自动完成汇编编译过程,如果各位同学要做逆向工程,汇编是必不可少的.

各位同学如是技术大牛请绕过,只是最近学汇编,发现的一些觉得有意思的事情.

 

下面从DOS汇编的角色来研究下面问题,因为win32汇编基本上能操作的底层太少了,得归于强大的编译器,包括栈区空间分配一些过程在编译时就已经固化了(vc栈空间大小默认为1M).我个人认为win32汇编开发基本上还是以调系统API为主

 

一. 程序为什么要以main函数为入口 

汇编直接从第一行代码开始执行,cs:0,如何有数据段,start标志起始位置,不存在main函数

VC下,真正的入口在mainCRTStartup或WinMainCRTStartup,在mainCRTStartup会调用main函数,如果没有main函数,则会提示编译错误. 也就说main函数入口是由编译器指定的

 

二. 字符串为什么要以'\0'结尾

C代码   收藏代码
  1. // 字符串拷贝:  
  2. void strcpy(char *dest,char *source)  
  3. {  
  4.     while((*dest++=*source++)!='\0');  
  5. }  
  6.    

   

    上面是字符串拷贝函数的实现,字符串以'\0'作为结束判断标志,那么汇编呢

Assembly代码   收藏代码
  1. data segment  
  2. db 'unix',0  
  3. db 0,0,0,0,0,0  
  4. data ends  
  5.    
  6. ; 将源字符串拷贝到下一行内存空间中  
  7. strcpy: mov cl,[si]  
  8. mov ch,0  
  9. jcxz ok   ;判断字符是否为0,为0则退出  
  10. mov byte ptr [si+5],cl ; 拷贝数据  
  11. inc si  
  12. inc di  
  13. jmp short strcpy  
  14. ok: ret  

 

 

三. 传值传参

C代码   收藏代码
  1. void swap(int a,int b)  
  2. {  
  3.   int temp = a;  
  4.   a = b;  
  5.   b = temp;  
  6. }  
  7.    
  8. int main()  
  9. {  
  10.   int a = 3;  
  11.   int b = 4;  
  12.    
  13.   swap(a,b);  
  14.   printf("%d %d\n",a,b);  
  15.    
  16.   return 0;  
  17. }  

 

大家一眼就能看出打印3 4,a和b的值都没有改变,都知道解释只是传值传参,所以不改变. 深入的同学会说,传值传参是复制a,b的实参值到形参,操作形参结果不影响实参. 再深入的同学说因为形参跟实参是两块不同的内存地址,必然不影响裸骑结果.大家都说的有道理,那我们来看看相应的汇编:

 

cdecl调用方式,由调用者管理堆栈平衡 

Assembly代码   收藏代码
  1. push b ;此时a,b数据被复制到栈区内,操作的是栈地址(dword ptr [ebp-4]),与原实参没任何关系  
  2. push a  
  3. call swap  
  4. add esp,4  ; 调整栈平衡  

  

stdcall调用方式,用于win32 API

Assembly代码   收藏代码
  1. push b  
  2. push a  
  3. call swap  ; 由函数自动维护栈平衡  

 

看上面汇编代码发现,全是在操作stack地址块,与a,b没关系.Java不支持指针操作,那如何交换a,b的值呢?java参数传递支持传值传递,引用传递两种方式.基本类型传值传递,对象通过引用传递. Java中对于这个问题没有好的解决方式,有一种通过数组(int[])取巧的方式

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值