在程序设计语言里面,循环是三种语言流程之一(顺序,分支,循环),这其中循环又是编程这件事中最具魅力的,它发挥了人在思维和计算机在计算方面的双方优势,体现了程序员的技巧和智慧,也体现了代码的简洁,优雅和优美。循环中最常用的应该是 for 循环,其他几种例如while,do while又基本上可以等效写成 for 循环。同时 for 循环又可以被等效改写为递归函数。本文首先通过VC创建一个含有for循环的简单函数的工程,然后用IDA工具分析其汇编代码。
for循环主要由以下形式组成,例如:
for( i = 0; i < imax; i++) { ... }
可以将其看做有四个基本部分构成,即初始化语句( i = 0 ), 条件语句(i < imax), 主体后续语句 (i++), 和供循环重复执行的主体({。。。})。首先用VC创建一个Win32 Console 程序,我们输入一个含有for循环的简单函数,代码如下:
#include < string .h >
int getstring( char * s)
{
int length = strlen(s);
int i;
for (i = 0 ; i < length; i ++ )
{
// 取余(%)优先级比加减(+-)高!
s[i] = (s[i] - ' a ' + 1 ) % 26 + ' a ' ;
}
return length;
}
int main( int argc, char * argv[])
{
char s[] = " abcdefg\0 " ;
int result = getstring(s);
printf( " %s\n " , s);
return 0 ;
}
简要介绍以下上面的代码,函数 getstring 用于对输入的字符串(假设输入的字符串全部有小写字母a-z组成),把字符串中每个字符改为其下一个英文字符(例如a改为b,b改为c,...,z改为a)。因此上面的程序我们在main里面初始化一个字符串为“abcdefg”,输出“bcdefgh”。
下面我们用IDA查看其反汇编代码(win32 debug):在汇编代码中,getstring 函数和 main 函数和我们的C++代码中出现的顺序相同,可以看到:
getstring 函数从 00401020H ~ 00401095H (代码量: 118 bytes,按 16bytes 对齐后实际占据 160bytes);
main 函数从 004010C0H ~ 00401124H (代码量:101 bytes, 对齐后实际占据 128 bytes);
在函数和函数之间,用0xCC进行填充,以使函数开始地址都位于16bytes整数倍处;
我们先简要看下 main 函数,很显然,字符串 s 是在 main函数内 的栈上空间:汇编代码如下: