在vs2005下建立vc++的win32 控制台应用程序,设置stdafx.h不必要包含,设置多字符集,设置汇编输出/FAs。代码和asm解析如下:
#include <stdio.h>
int main(int argc, char* argv[])
{
char c = 'C';
int i = 9;
double d(0.1);
for(; i%2; --i)
d += c;
printf("%f/n", d);
return 0;
}
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES
PUBLIC ??_C@_03PPOCCAPH@?$CFf?6?$AA@ ; `string'
PUBLIC __real@3fb999999999999a;浮点常量的名字
PUBLIC _main
EXTRN __imp__printf:PROC
EXTRN __fltused:DWORD;浮点运算相关的关键字声明,未明
EXTRN __RTC_CheckEsp:PROC
EXTRN __RTC_Shutdown:PROC
EXTRN __RTC_InitBase:PROC
CONST SEGMENT
??_C@_03PPOCCAPH@?$CFf?6?$AA@ DB '%f', 0aH, 00H ; `string'
CONST ENDS
CONST SEGMENT
__real@3fb999999999999a DQ 03fb999999999999ar ; 0.1;浮点常量
CONST ENDS
rtc$TMZ SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ ENDS
rtc$IMZ SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
rtc$IMZ ENDS
_TEXT SEGMENT
tv75 = -236 ; size = 4;为浮点加法准备的临时变量
_d$ = -36 ; size = 8;变量d的栈内相对地址
_i$ = -20 ; size = 4;同上
_c$ = -5 ; size = 1
_argc$ = 8 ; size = 4;argc的栈内相对地址
_argv$ = 12 ; size = 4
_main PROC ; COMDAT
; 3 : {
push ebp
mov ebp, esp
sub esp, 236 ; 000000ecH
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-236]
mov ecx, 59 ; 0000003bH
mov eax, -858993460 ; ccccccccH
rep stosd
; 4 : char c = 'C';
mov BYTE PTR _c$[ebp], 67 ; 00000043H;给变量c赋值
; 5 : int i = 9;
mov DWORD PTR _i$[ebp], 9;给变量i赋值
; 6 : double d(0.1);
fld QWORD PTR __real@3fb999999999999a;float load。将浮点数据压入协处理器的堆栈中
fstp QWORD PTR _d$[ebp];将协处理器堆栈里的浮点数store到ebp + _d所指向的浮点变量d
jmp SHORT $LN3@main;此处跳到i%2编译的代码处
$LN2@main:
; 7 : for(; i%2; --i)
mov eax, DWORD PTR _i$[ebp];--i编译后的代码
sub eax, 1
mov DWORD PTR _i$[ebp], eax
$LN3@main:
mov eax, DWORD PTR _i$[ebp]
and eax, -2147483647 ; 80000001H;求余判断的优化代码开始
jns SHORT $LN6@main;Jump if Not Signed
dec eax
or eax, -2 ; fffffffeH;最后一位为0
inc eax
$LN6@main:
test eax, eax;Test For Bit Pattern
je SHORT $LN1@main
; 8 : d += c;
movsx eax, BYTE PTR _c$[ebp];以byte指针解释ebp+_c处的值,存入eax
mov DWORD PTR tv75[ebp], eax;放入临时变量
fild DWORD PTR tv75[ebp];将临时变量的值load到协处理器的堆栈中,大概带扩展bit的功能
fadd QWORD PTR _d$[ebp];浮点加法
fstp QWORD PTR _d$[ebp]
jmp SHORT $LN2@main;到--i处
$LN1@main:
; 9 : printf("%f/n", d);
mov esi, esp
sub esp, 8
fld QWORD PTR _d$[ebp]
fstp QWORD PTR [esp]
push OFFSET ??_C@_03PPOCCAPH@?$CFf?6?$AA@
call DWORD PTR __imp__printf
add esp, 12 ; 0000000cH
cmp esi, esp
call __RTC_CheckEsp
; 10 : return 0;
xor eax, eax
; 11 : }
pop edi
pop esi
pop ebx
add esp, 236 ; 000000ecH
cmp ebp, esp
call __RTC_CheckEsp
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END