以前在百度的博客里面学习了逆向一些基本的C语言知识。一方面不能让学习的汇编知识荒废,另外一方面是由于经常碰到一些细节性的问题,需要温故而知新。

学习汇编对于我自己的感觉是:可以从更加底层的角度来窥视C语言以及其他高层语言的细节。这是一件很舒服的事情~

同时一些特殊的工作,比如内核调试,内存错误,函数调用等问题,用汇编的角度来看待会更加方便,更加深刻的理解其机制。

废话不多说,作为开篇《汇编的艺术》,是我今天更巧碰到的一个问题,想记下来,先从最简单的入手,感觉是慢慢来的~

先看一段代码:

int main()
{  char a = 255;  printf("%d\n",sizeof(++a));  printf("%d\n",a);  return 0;
}  

出乎意料的是,输出的值是:1,-1

难道是sizeof里面的++a没有执行么?带着这样的疑问,看看反汇编代码是啥样的:

int main()
{  char a = 255;
00000000  push        ebp
00000001  mov         ebp,esp
00000003  sub         esp,8
00000006  cmp         dword ptr ds:[00192E14h],0
0000000d  je          00000014
0000000f  call        696E67F9
00000014  xor         edx,edx
00000016  mov         dword ptr [ebp-4],edx
00000019  mov         dword ptr [ebp-8],0
00000020  xor         edx,edx
00000022  mov         dword ptr [ebp-4],edx
00000025  mov         dword ptr [ebp-8],0FFFFFFFFh printf("%d\n",sizeof(++a));
0000002c  push        1B31B8h
00000031  push        1
00000033  push        4F01B8h
00000038  call        FEEA58CC
0000003d  add         esp,0Ch
00000040  nop              printf("%d\n",a);
00000041  push        1B31BCh
00000046  push        dword ptr [ebp-8]
00000049  push        4F01C8h
0000004e  call        FEEA58CC
00000053  add         esp,0Ch
00000056  nop              return 0;
00000057  xor         edx,edx
00000059  mov         dword ptr [ebp-4],edx
}
0000005c  mov         eax,dword ptr [ebp-4]
0000005f  mov         esp,ebp
00000061  pop         ebp
00000062  ret              

看到橙黄色标注的部分,果然传参的时候是直接push了1,而++a这个指令在没有在汇编中出现的痕迹。

但是sizeof操作符并不像#define这样的宏一样在预处理阶段就把其替换掉了,sizeof是在编译阶段替换的。

于是理解了,sizeof里面的expression都是不执行的,只关心里面类型的大小。

类似的问题还有sizeof('a'),貌似不同的编译器说法不一,C标准应该是把'a'看成了97,也就是int类型,等于4,

如果里面的数字再大的话,超过了int范围,则是8了,以此类推。

还有是sizeof("a"),这个问题不该有争议,因为传进去的是字符串a的地址,就是一个指针的大小了,32位机器上面是4,64位机器上面应该是8.

btw:

很久没有看过反汇编代码了,很多东西都生疏了。

比如说里面不理解的是,main()函数明明只申请了一个char 的却把栈空间抬高了8个字节,边界对齐为char开辟4字节还能理解。

那另外的4个字节又是什么意思呢?函数最后返回的代码利用到了这4个字节,把里面的值传给eax。

这是汇编的风格,函数的返回值是传给eax的。但是不清楚为什么还要“多此一举”。

我的理解是,因为函数最终要返回的,对于一般的函数如果返回比如 return ans; ans变量肯定要开辟字节空间的,于是return 0; 也按照这个思路照做了?有时间再探究。

第二个问题就是又一次的复习了函数传参时堆栈的情况。感觉都有点生疏了。

printf 第一个参数压入的是格式化字符串的地址,后面压入的几个参数则是变量。对于这类参数可变的函数,平衡堆栈的工作要交给母函数来处理的。

关于这方面详细的介绍请看:http://bbs.pediy.com/showthread.php?t=56518

转载于:https://www.cnblogs.com/kedebug/archive/2012/12/03/2800225.html

汇编的艺术(01)sizeof operator相关推荐

  1. R语言编程艺术#01#数据类型向量(vector)

    R语言最基本的数据类型-向量(vector) 1.插入向量元素,同一向量中的所有的元素必须是相同的模式(数据类型),如整型.数值型(浮点数).字符型(字符串).逻辑型.复数型等.查看变量的类型可以用t ...

  2. 关于sizeof的一些东西

    今天写POJ 2737 大数运算的时候,突然发现自己以前关于sizeof运算符的理解有点错误,于是认真查阅了一点资料,编程实现了一些东西,写篇文章总结一下. 先看下MSDN上关于sizeof的解释: ...

  3. sizeof()与strlen()的区别与联系

    从外部特性来看: #include <stdio.h> #include <string> int main() { char array[] = "12345&qu ...

  4. sizeof和strlen()区别

    2017-12-19 创建人:Ruo_Xiao 邮箱:xclsoftware@163.com 2018-01-16 修改人:Ruo_Xiao 增加strlen的头文件的说明. #include &qu ...

  5. c# sizeof_C#程序演示sizeof()运算符的示例

    c# sizeof C#sizeof()运算符 (C# sizeof() operator) It is used to obtain the size of a data type in bytes ...

  6. 运算符sizeof_C程序通过使用sizeof()运算符对数组元素进行计数

    运算符sizeof sizeof() operator returns the total number of size occupied by a variable, since array is ...

  7. 数组名不等于指针---sizeof()函数求数组大小错误问题

    前言: 今天在项目中需要求采样点的数量并且遍历,采样点用数组存储,自定义了一个函数想要用sizeof求其长度,然后遍历,结果失败了,查阅之后发现以下问题: 在main函数中,sizeof是可以正常工作 ...

  8. sizeof运算符_C编程中的sizeof()运算符

    sizeof运算符 Like many other programming languages, C also comes with some pre-defined functions. sizeo ...

  9. C语言sizeof的用法及注意事项

    C语言sizeof的用法及注意事项 求普通变量的大小 #include <stdio.h> int main() {int a = 5;printf ("%d\n", ...

最新文章

  1. 关于C语言中 字符串常量的问题
  2. lodop打印无内容_民法典新确立的打印遗嘱应如何订立能有效?| 附文书范本
  3. 高分求FP-tree算法用Delphi实现
  4. 1096 Consecutive Factors (20 分)_24行代码AC
  5. 【推荐】介绍两款Windows资源管理器,Q-Dir 与 FreeCommander XE(比TotalCommander更易用的免费资源管理器)...
  6. 容器安全 - 限制docker/podman只能使用有效签名的镜像
  7. asp 图片上传源码 【亲测】
  8. 陈皓:不灌鸡汤,说真的年龄渐长,技术人的发展之路该怎么走?
  9. c语言作业模块化设计具体,C语言程序模块化设计.doc
  10. matlab hog函数个参数,hog算法的matlab
  11. 关于研究课题中的技术路线与实施方案
  12. ###【Python版本】股票行情API:获取A股主流指数成分股st股和次新股日内资金净流入A股个股实时盘口/历史行情数据基本财务数据/现金流量数据央行货币供应数据融资融券历史数据的Api
  13. E-chart官方源码下载和关系图搭建
  14. 使用STAR进行RNA-seq数据比对
  15. 在c语言中如何区别%s和%c
  16. 【WINDOWS / DOS 批处理】for命令详解(八)
  17. 详细讲解vc 6.0进行DDK驱动开发【原创】
  18. C++与QML混合编程
  19. 商务服务-建站设计思路搜索引擎SEO模型
  20. CRM(客户关系管理)项目总结

热门文章

  1. PHP 过滤器(Filter)
  2. 老干妈如今做到这么大,为什么她就是没遇到竞敌?
  3. 老公贷款还不上,妻子有偿还责任吗?
  4. 伯颜的诗和“金佛”趣事
  5. 成吉思汗:“世界之鞭”还是“人类之王”?
  6. 单片机小白学步系列(四) 模拟电路、传统数字电路与单片机
  7. VHDL中的左移函数
  8. 代码统计工具有哪几种_跟我学“Linux”小程序Web版开发(四):引入统计及Crash收集...
  9. openstack实例控制台显示响应时间过长_监控OpenStack的技巧
  10. EM算法(Expectation Maximization Algorithm)