在C语言中循环会用到for和while结构,现在对比一下。
先看看for循环。C语言代码:
#include <stdio.h>
int main()
{
int x = 0;
for (int i = 1;i <= 100;i++)
x = x + i;
return 0;
}
这段代码用来计算1到100累计相加的结果,编译后使用IDA进行分析,看反汇编代码:
.text:00401000 push ebp
.text:00401001 mov ebp, esp
.text:00401003 sub esp, 8
.text:00401006 mov [ebp+x], 0
.text:0040100D mov [ebp+i], 1
这里定义了两个int型的变量x和i,分别给它们赋值0和1
.text:00401014 jmp short loc_40101F
.text:00401016 mov eax, [ebp+i]
.text:00401019 add eax, 1
.text:0040101C mov [ebp+i], eax
.text:0040101F cmp [ebp+i], 64h
.text:00401023 jg short loc_401030
.text:00401025 mov ecx, [ebp+x]
.text:00401028 add ecx, [ebp+i]
.text:0040102B mov [ebp+x], ecx
.text:0040102E jmp short loc_401016
这里是循环体的代码。在对变量x和i初始化以后直接跳到0x0040101F处把循环变量和0x64进行比较,0x64就是十进制的100,当循环变量i大于0x64时则跳出循环体,如果循环变量i不大于0x64时,把变量x和变量i相加,结果存回变量x,然后跳回循环头部,使循环变量i自增1,然后再次和0x64进行比较,直到循环变量i大于0x64才退出循环。
.text:00401030 xor eax, eax
.text:00401032 mov esp, ebp
.text:00401034 pop ebp
.text:00401035 retn
再来看一看while循环的方式:
#include <stdio.h>
int main()
{
int x = 0;
int i = 101;
while (i--)
x = x + i;
return 0;
}
同样是一段计算1到100累计相加的结果的代码,编译后使用IDA进行分析,看反汇编代码:
.text:00401000 push ebp
.text:00401001 mov ebp, esp
.text:00401003 sub esp, 8
.text:00401006 mov [ebp+x], 0
.text:0040100D mov [ebp+i], 65h
这里定义了两个int型的变量x和i,分别给它们赋值0和0x65,0x65即十进制的101
.text:00401014 mov eax, [ebp+i]
.text:00401017 mov ecx, [ebp+i]
.text:0040101A sub ecx, 1
.text:0040101D mov [ebp+i], ecx
.text:00401020 test eax, eax
.text:00401022 jz short loc_40102F
.text:00401024 mov edx, [ebp+x]
.text:00401027 add edx, [ebp+i]
.text:0040102A mov [ebp+x], edx
.text:0040102D jmp short loc_401014
这一部分是循环体的代码,取出变量i的值,放入寄存器eax和ecx中,使ecx减1,然后存回变量i中,接下来使用test指令测试eax是不是0,eax是还没有减1前的变量i的值,如果eax等于0则跳出循环体部分,否则不执行跳转,把变量x和变量i相加,结果存回变量x,最后跳回循环头部重新计算。
.text:0040102F xor eax, eax
.text:00401031 mov esp, ebp
.text:00401033 pop ebp
.text:00401034 retn
while循环还有一种形式为do-while结构:
#include <stdio.h>
int main()
{
int x = 0;
int i = 100;
do{
x = x + i;
} while (--i);
return 0;
}
依然一段计算1到100累计相加的结果的代码,编译后使用IDA进行分析,看反汇编代码:
.text:00401000 push ebp
.text:00401001 mov ebp, esp
.text:00401003 sub esp, 8
.text:00401006 mov [ebp+x], 0
.text:0040100D mov [ebp+i], 64h
这里定义了两个int型的变量x和i,分别给它们赋值0和0x64,0x64即十进制的100。
.text:00401014 mov eax, [ebp+x]
.text:00401017 add eax, [ebp+i]
.text:0040101A mov [ebp+x], eax
.text:0040101D mov ecx, [ebp+i]
.text:00401020 sub ecx, 1
.text:00401023 mov [ebp+i], ecx
.text:00401026 jnz short loc_401014
这一段是循环体的代码。把变量x和变量i相加,然后把结果存回变量x中,然后取变量i的值,减1后把结果存回变量i中,最后跳到循环头部重新计算。
.text:00401028 xor eax, eax
.text:0040102A mov esp, ebp
.text:0040102C pop ebp
.text:0040102D retn