从汇编角度分析自增、自减
在分析前我们先看一段C代码(wintc or gcc 都可以编译成功):
#include <stdio.h>
int main()
{
int k0;
int k1;
int k2;
int k3;
int k4;
k0 = 0;
k1 = 0;
k2 = 0;
k3 = 0;
k4 = 0;
step1:
k0 = 11;
k1 = 2;
k4 = ++k0 + k1-- + ++k0;
printf("%d %d\n", k4, k0);
step2:
k0 = 11;
k1 = 2;
k4 = k0++ + ++k0 + ++k0;
printf("%d %d\n", k4, k0);
step3:
k0 = 11;
k1 = 2;
k4 = ++k0 + ++k0 + k0++;
printf("%d %d\n", k4, k0);
step4:
k0 = 11;
k1 = 2;
k4 = ++k0 + k0++ + ++k0;
printf("%d %d\n", k4, k0);
step5:
k0 = 11;
k1 = 2;
k4 = k0++/k1++ + ++k1 + k1++ + ++k1;
printf("%d %d\n", k4, k0);
end:
getchar();
return 0;
}
这是一段非常简单的代码,代码中仅涉及到 定义变量,自增、自减、加法、除法运算和打印输出。
那么我们看一下它的输出结果:
/****************wintc*****************/
28 13
39 14
39 14
39 14
14 12
/****************gcc*****************/
27 13
37 14
39 14
37 14
15 12
现在许多读者都会有疑问了,表面上看同样一段C代码 编译器不一样获得的结果也不一样。而且有许多读者会得出与以上完全不同的结果,或者根本就不知如何下手。
那么我们来看看他们的汇编代码:
/*************windows********************/
ifndef ??version
?debug macro
endm
endif
?debug S "aaa.c"
AAA_TEXT segment byte public 'CODE'
DGROUP group _DATA,_BSS
assume cs:AAA_TEXT,ds:DGROUP,ss:DGROUP
AAA_TEXT ends
_DATA segment word public 'DATA'
d@ label byte
d@w label word
_DATA ends
_BSS segment word public 'BSS'
b@ label byte
b@w label word
?debug C E949A0F940056161612E63
?debug C E957A7972619433A5C57696E2D54435C494E434C5544455C737464+
?debug C 696F2E68
?debug C E957A797261A433A5C57696E2D54435C494E434C5544455C737464+
?debug C 6172672E68
_BSS ends
AAA_TEXT segment byte public 'CODE'
; ?debug L 2
_main proc far
push bp
mov bp,sp
sub sp,6
push si
push di
; ?debug L 10
xor si,si ; k0 = 0
; ?debug L 11
xor di,di ; k1 = 0
; ?debug L 12
mov word ptr [bp-6],0 ; k2 = 0
; ?debug L 13
mov word ptr [bp-4],0 ; k3 = 0
; ?debug L 14
mov word ptr [bp-2],0 ; k4 = 0
@2:
;/
;k4 = ++k0 + k1-- + ++k0
;k4:28 = 13 + 2 + 13 k0:13
;
在分析前我们先看一段C代码(wintc or gcc 都可以编译成功):
#include <stdio.h>
int main()
{
int k0;
int k1;
int k2;
int k3;
int k4;
k0 = 0;
k1 = 0;
k2 = 0;
k3 = 0;
k4 = 0;
step1:
k0 = 11;
k1 = 2;
k4 = ++k0 + k1-- + ++k0;
printf("%d %d\n", k4, k0);
step2:
k0 = 11;
k1 = 2;
k4 = k0++ + ++k0 + ++k0;
printf("%d %d\n", k4, k0);
step3:
k0 = 11;
k1 = 2;
k4 = ++k0 + ++k0 + k0++;
printf("%d %d\n", k4, k0);
step4:
k0 = 11;
k1 = 2;
k4 = ++k0 + k0++ + ++k0;
printf("%d %d\n", k4, k0);
step5:
k0 = 11;
k1 = 2;
k4 = k0++/k1++ + ++k1 + k1++ + ++k1;
printf("%d %d\n", k4, k0);
end:
getchar();
return 0;
}
这是一段非常简单的代码,代码中仅涉及到 定义变量,自增、自减、加法、除法运算和打印输出。
那么我们看一下它的输出结果:
/****************wintc*****************/
28 13
39 14
39 14
39 14
14 12
/****************gcc*****************/
27 13
37 14
39 14
37 14
15 12
现在许多读者都会有疑问了,表面上看同样一段C代码 编译器不一样获得的结果也不一样。而且有许多读者会得出与以上完全不同的结果,或者根本就不知如何下手。
那么我们来看看他们的汇编代码:
/*************windows********************/
ifndef ??version
?debug macro
endm
endif
?debug S "aaa.c"
AAA_TEXT segment byte public 'CODE'
DGROUP group _DATA,_BSS
assume cs:AAA_TEXT,ds:DGROUP,ss:DGROUP
AAA_TEXT ends
_DATA segment word public 'DATA'
d@ label byte
d@w label word
_DATA ends
_BSS segment word public 'BSS'
b@ label byte
b@w label word
?debug C E949A0F940056161612E63
?debug C E957A7972619433A5C57696E2D54435C494E434C5544455C737464+
?debug C 696F2E68
?debug C E957A797261A433A5C57696E2D54435C494E434C5544455C737464+
?debug C 6172672E68
_BSS ends
AAA_TEXT segment byte public 'CODE'
; ?debug L 2
_main proc far
push bp
mov bp,sp
sub sp,6
push si
push di
; ?debug L 10
xor si,si ; k0 = 0
; ?debug L 11
xor di,di ; k1 = 0
; ?debug L 12
mov word ptr [bp-6],0 ; k2 = 0
; ?debug L 13
mov word ptr [bp-4],0 ; k3 = 0
; ?debug L 14
mov word ptr [bp-2],0 ; k4 = 0
@2:
;/
;k4 = ++k0 + k1-- + ++k0
;k4:28 = 13 + 2 + 13 k0:13
;