在vs2005下建立vc++的win32 控制台应用程序,设置stdafx.h不必要包含,设置多字符集,设置汇编输出/FAs。编写代码如下:
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("hello world!/n");
return 0;
}
对应的汇编输出为:
; Listing generated by Microsoft (R) Optimizing Compiler Version 14.00.50727.42
TITLE e:/study/tc/t03/t03.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES
PUBLIC ??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@ ; `string'
PUBLIC _main
EXTRN __imp__printf:PROC
EXTRN __RTC_CheckEsp:PROC
EXTRN __RTC_Shutdown:PROC
EXTRN __RTC_InitBase:PROC
; COMDAT ??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@
; File e:/study/tc/t03/t03.cpp
CONST SEGMENT
??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@ DB 'hello world!', 0aH, 00H ; `string'
CONST ENDS
; COMDAT rtc$TMZ
rtc$TMZ SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ ENDS
; COMDAT rtc$IMZ
rtc$IMZ SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
; Function compile flags: /Odtp /RTCsu /ZI
rtc$IMZ ENDS
; COMDAT _main
_TEXT SEGMENT
_argc$ = 8 ; size = 4
_argv$ = 12 ; size = 4
_main PROC ; COMDAT
; 3 : {
push ebp
mov ebp, esp
sub esp, 192 ; 000000c0H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-192]
mov ecx, 48 ; 00000030H
mov eax, -858993460 ; ccccccccH
rep stosd
; 4 : printf("hello world!/n");
mov esi, esp
push OFFSET ??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@
call DWORD PTR __imp__printf
add esp, 4
cmp esi, esp
call __RTC_CheckEsp
; 5 : return 0;
xor eax, eax
; 6 : }
pop edi
pop esi
pop ebx
add esp, 192 ; 000000c0H
cmp ebp, esp
call __RTC_CheckEsp
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
胡乱解释如下:
.686P;指定使用的指令集
.XMM;不清楚,XMM寄存器?新的指令集、寄存器相关。
include listing.inc;包含头文件。
.model flat;指定内存模式
;包含lib
INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES
;符号集,本程序只涉及6个符号
PUBLIC ??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@ ; `string'
PUBLIC _main
EXTRN __imp__printf:PROC;外部函数名
EXTRN __RTC_CheckEsp:PROC
EXTRN __RTC_Shutdown:PROC
EXTRN __RTC_InitBase:PROC
CONST SEGMENT;const数据段定义
??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@ DB 'hello world!', 0aH, 00H ; `string'
CONST ENDS
rtc$TMZ SEGMENT;外部函数段?
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ ENDS
; COMDAT rtc$IMZ
rtc$IMZ SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
; Function compile flags: /Odtp /RTCsu /ZI
rtc$IMZ ENDS
_TEXT SEGMENT;主要代码段?
_argc$ = 8 ; size = 4
_argv$ = 12 ; size = 4
_main PROC ; COMDAT
; 3 : { ; ";"号表示注释,此处对应代码第3行
push ebp;EBP:Base Pointer进栈,保存main函数的上级调用函数的栈基地址
mov ebp, esp;设置当前函数的栈基址
sub esp, 192 ; 000000c0H
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-192];LEA - Load Effective Address
mov ecx, 48 ; 00000030H
mov eax, -858993460 ; ccccccccH
rep stosd;STOS - Store String (Byte, Word or Doubleword)
; 4 : printf("hello world!/n");
mov esi, esp
push OFFSET ??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@ ;string的地址进栈
call DWORD PTR __imp__printf;函数调用
add esp, 4;函数参数空间的回收
cmp esi, esp;检查栈顶是否有误
call __RTC_CheckEsp
; 5 : return 0;
xor eax, eax;XOR - Exclusive OR,eax寄存器是函数返回值保存的地方
; 6 : }
pop edi;开始恢复调用_main函数之前的寄存器,并检查栈顶
pop esi
pop ebx
add esp, 192 ; 000000c0H
cmp ebp, esp
call __RTC_CheckEsp
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS