自学内容网 自学内容网

128.【C语言】补充:循环结束后循环变量的值(反汇编分析)

目录

0.准备工作

1.反汇编下列C代码

2.反汇编后

分析

先了解下jge指令

格式

逐指令分析

3.结论

4.拓展问题


0.准备工作

运行环境:VS2022+Debug+X86

1.反汇编下列C代码

int main()
{
int i, a;
for (i = 0; i < 5; i++)
{
a = 1;
}
return 0;
}
 

2.反汇编后

int main()
{
 push        ebp  
 mov         ebp,esp  
 sub         esp,48h  
 push        ebx  
 push        esi  
 push        edi  
 mov         ecx,offset _2AFA38E1_FileName@c   
 call        @__CheckForDebuggerJustMyCode@4 
 nop  
int i, a;
for (i = 0; i < 5; i++)
 mov         dword ptr [i],0  
 jmp         main+26h 
 mov         eax,dword ptr [i]  
 add         eax,1  
 mov         dword ptr [i],eax  
 cmp         dword ptr [i],5  
 jge         main+35h 
{
a = 1;
 mov         dword ptr [a],1  
}
 jmp         main+1Dh 
return 0;
 xor         eax,eax  
}
 pop         edi  
 pop         esi  
 pop         ebx  
 mov         esp,ebp  
 pop         ebp  
 ret  

分析

先了解下jge指令

jge(jump if greater or equal)为条件跳转指令,用于有符号数的比较(原因:i是int类型,VS默认int为signed int类型,即有符号整型)

格式
cmp dest, src
jge label

dest和src当有符号数看待,如果dest>=src,跳转到标号label处执行

逐指令分析

先回忆下for循环的结构

for (初始化;判断部分;调整部分)
{
    //循环体
}

对照到反汇编指令后:

初始化后先判断一次(jmp main+26h),之后反复执行循环体

为i++使用寄存器eax做中转是惯用的手段

eax = i;

eax++;

i=eax;

注意到判断部分:

 cmp         dword ptr [i],5  
 jge         main+35h 

先将i与5做比较,如果i>=5则退出循环,来到return 0;处 ,因此当i==5(即i==n)时会直接退出循环,不会等到i>5的情况发生

3.结论

由上得出,下列代码的循环执行结束后,i的值为n!!!(不是说循环条件为i<n,i就取不到n,只是说明i==n参与不了循环)

int i;
for (i=0;i<n;i++)
{
    //do_something
}

4.拓展问题

将代码的int i,a改成unsigned int,反汇编看看与原来有什么区别

只有cmp下面的比较指令变了

 cmp         dword ptr [i],5  
 jae         main+35h 

jae:jae(jump if above or equal)为条件跳转指令,用于无符号数的比较(因为i是unsigned int类型)

看来循环变量的类型会影响条件跳转指令的类型


原文地址:https://blog.csdn.net/2401_85828611/article/details/145134469

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!