汇编的艺术(01)sizeof operator
以前在百度的博客里面学习了逆向一些基本的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
kedebug
Department of Computer Science and Engineering,
Shanghai Jiao Tong University
E-mail: kedebug0@gmail.com
GitHub: http://github.com/kedebug
-------------------------------------------------------