CPU指令本质上是顺序执行的,但可以实现跳转(向后跳转可形成循环语句,后前跳转可形成选择分支语句)。
1 条件选择语句与cmp和JCC汇编指令
看C语句与对应的汇编代码:
6: int a=3;00401578 mov dword ptr [ebp-4],37: int b=4;0040157F mov dword ptr [ebp-8],48: int max;9: if(b>a)00401586 mov eax,dword ptr [ebp-8]00401589 cmp eax,dword ptr [ebp-4]0040158C jle main+36h (00401596)10: max = b;0040158E mov ecx,dword ptr [ebp-8]00401591 mov dword ptr [ebp-0Ch],ecx11: else00401594 jmp main+3Dh (0040159d)12: max = 0;00401596 mov dword ptr [ebp-0Ch],013: cout<
当执行到CMP指令的时候会读取这两个寄存器的内容,并做减法运算,结果本身不保留,只按照结果设置符号位(标志位)。
如:
CMP R1, R0 将寄存器R1的值与寄存器R0的值相减,并根据结果设置标志位。
CMP R1,#100 将寄存器R1的值与立即数100相减,并根据结果设置标志位。
cmp eax,dword ptr [ebp-4] 寄存器eax减去栈中[ebp-4],根据结果设置标志位。
标志位表示的是操作数1与操作数2的关系(大、小、相等)。这些符号位存在一个叫做PSW(Program Status Word,程序状态字)的16位(4字节)寄存器里面。
JCC指条件跳转指令,CC就是指条件码,是指一系列是J开头的条件跳转指令。
JLE,是jump if less equal的缩写,若小于等于则跳转(检查符号位ZF != OF 或 ZF=1)。
2 循环的实质也是按条件跳转(向后跳转)
看C语句与对应的汇编代码:
15: int i = 1;004015B7 mov dword ptr [ebp-10h],116: int sum = 0;004015BE mov dword ptr [ebp-14h],017: while(i<=100)004015C5 cmp dword ptr [ebp-10h],64h004015C9 jg main+7Fh (004015df)18: {19: sum+=i;004015CB mov eax,dword ptr [ebp-14h]004015CE add eax,dword ptr [ebp-10h]004015D1 mov dword ptr [ebp-14h],eax20: ++i;004015D4 mov ecx,dword ptr [ebp-10h]004015D7 add ecx,1004015DA mov dword ptr [ebp-10h],ecx21: }004015DD jmp main+65h (004015c5)22: cout<
JG(jump if greater),若大于则跳转(检查标志位:SF=0F 且 ZF=0)。
jmp(jump)是无条件跳转。
for循环只是将控制循环的变量的初始化、更新和比较的语句聚集到了一起:
25: for(int i=1;i<=100;++i)004015BE mov dword ptr [ebp-14h],1004015C5 jmp main+70h (004015d0)004015C7 mov eax,dword ptr [ebp-14h]004015CA add eax,1004015CD mov dword ptr [ebp-14h],eax004015D0 cmp dword ptr [ebp-14h],64h004015D4 jg main+81h (004015e1)26: sum+=i;004015D6 mov ecx,dword ptr [ebp-10h]004015D9 add ecx,dword ptr [ebp-14h]004015DC mov dword ptr [ebp-10h],ecx004015DF jmp main+67h (004015c7)27: cout<
以下循环也可以用比较语句和goto语句来实现:
28: int i = 1;004015BE mov dword ptr [ebp-14h],129: backLoopPoint:30: sum+=i;004015C5 mov eax,dword ptr [ebp-10h]004015C8 add eax,dword ptr [ebp-14h]004015CB mov dword ptr [ebp-10h],eax31: ++i;004015CE mov ecx,dword ptr [ebp-14h]004015D1 add ecx,1004015D4 mov dword ptr [ebp-14h],ecx32: if(i<=100)004015D7 cmp dword ptr [ebp-14h],64h004015DB jg backLoopPoint+1Ah (004015df)33: goto backLoopPoint;004015DD jmp backLoopPoint (004015c5)34: cout<
附jcc指令表
-End-