macro.asm
以下のコードを自分で「macro.asm」と保存すればいいです.親測定CTXT(「Hi.i'm Sollyu.」)通過!
; ###########################################################################
;
; Support macros for MASM32
;
; ###########################################################################
; ----------------------------------------------------------
; load a library and get the procedure address in one macro
; return value for the proc address in in EAX
; ----------------------------------------------------------
LoadProcAddress MACRO quoted_text1,quoted_text2
LOCAL library_name
LOCAL proc_name
.data
library_name db quoted_text1,0
proc_name db quoted_text2,0
.code
invoke LoadLibrary,ADDR library_name
invoke GetProcAddress,eax,ADDR proc_name
ENDM
; -------------------------
; initialised GLOBAL value
; -------------------------
GLOBAL MACRO variable:VARARG
.data
variable
.code
ENDM
; --------------------------------
; initialised GLOBAL string value
; --------------------------------
STRING MACRO variable:REQ,args:VARARG
.data
variable db args,0
.code
ENDM
; ---------------------
; literal string MACRO
; ---------------------
literal MACRO quoted_text:VARARG
LOCAL local_text
.data
local_text db quoted_text,0
.code
EXITM <local_text>
ENDM
; --------------------------------
; string address in INVOKE format
; --------------------------------
SADD MACRO quoted_text:VARARG
EXITM <ADDR literal(quoted_text)>
ENDM
; --------------------------------
; string OFFSET for manual coding
; --------------------------------
CTXT MACRO quoted_text:VARARG
EXITM <offset literal(quoted_text)>
ENDM
; --------------------------------------------------
; Two macros for allocating and freeing OLE memory.
; stralloc returns the handle/address of the string
; memory in eax. strfree uses the handle to free
; memory after use.
; NOTE that you must use the following INCLUDE &
; LIB files with these two macros.
;
; include \MASM32\include\oleaut32.inc
; includelib \MASM32\LIB\oleaut32.lib
;
; --------------------------------------------------
stralloc MACRO ln
invoke SysAllocStringByteLen,0,ln
ENDM
strfree MACRO strhandle
invoke SysFreeString,strhandle
ENDM
; -------------------------------------------------------------------
; The following 2 macros are for limiting the size of a window while
; it is being resized. They are to be used in the WM_SIZING message.
; -------------------------------------------------------------------
LimitWindowWidth MACRO wdth
LOCAL label
mov eax, lParam
mov ecx, (RECT PTR [eax]).right
sub ecx, (RECT PTR [eax]).left
cmp ecx, wdth
jg label
.if wParam == WMSZ_RIGHT || wParam == WMSZ_BOTTOMRIGHT || wParam == WMSZ_TOPRIGHT
mov ecx, (RECT PTR [eax]).left
add ecx, wdth
mov (RECT PTR [eax]).right, ecx
.elseif wParam == WMSZ_LEFT || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_TOPLEFT
mov ecx, (RECT PTR [eax]).right
sub ecx, wdth
mov (RECT PTR [eax]).left, ecx
.endif
label:
ENDM
LimitWindowHeight MACRO whgt
LOCAL label
mov eax, lParam
mov ecx, (RECT PTR [eax]).bottom
sub ecx, (RECT PTR [eax]).top
cmp ecx, whgt
jg label
.if wParam == WMSZ_TOP || wParam == WMSZ_TOPLEFT || wParam == WMSZ_TOPRIGHT
mov ecx, (RECT PTR [eax]).bottom
sub ecx, whgt
mov (RECT PTR [eax]).top, ecx
.elseif wParam == WMSZ_BOTTOM || wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_BOTTOMRIGHT
mov ecx, (RECT PTR [eax]).top
add ecx, whgt
mov (RECT PTR [eax]).bottom, ecx
.endif
label:
ENDM
; ---------------------------------------
; Append literal string to end of buffer
; ---------------------------------------
Append MACRO buffer,text
LOCAL szTxt
.data
szTxt db text,0
.code
invoke szCatStr,ADDR buffer,ADDR szTxt
ENDM
; ---------------------------
; Put ascii zero at 1st byte
; ---------------------------
zero1 MACRO membuf
mov membuf[0], 0
ENDM
; -------------------------
; Application startup code
; -------------------------
AppStart MACRO
.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke InitCommonControls
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax
ENDM
ShellAboutBox MACRO handle,IconHandle,quoted_Text_1,quoted_Text_2:VARARG
LOCAL AboutTitle,AboutMsg,buffer
.data
AboutTitle db quoted_Text_1,0
AboutMsg db quoted_Text_2,0
buffer db 128 dup (0)
.code
mov esi, offset AboutTitle
mov edi, offset buffer
mov ecx, lengthof AboutTitle
rep movsb
invoke ShellAbout,handle,ADDR buffer,ADDR AboutMsg,IconHandle
ENDM
; --------------------------------------------------------------
; Specifies processor, memory model & case sensitive option.
; The parameter "Processor" should be in the form ".386" etc..
; EXAMPLE : AppModel .586
; --------------------------------------------------------------
AppModel MACRO Processor
Processor ;; Processor type
.model flat, stdcall ;; 32 bit memory model
option casemap :none ;; case sensitive
ENDM
; --------------------------------------------
; The following two macros must be used as a
; pair and can only be used once in a module.
; Additional code for processing within the
; message loop can be placed between them.
;
; The single parameter passed to both macros
; is the name of the MSG structure and must be
; the same in both macros.
; --------------------------------------------
BeginMessageLoop MACRO mStruct
MessageLoopStart:
invoke GetMessage,ADDR mStruct,NULL,0,0
cmp eax, 0
je MessageLoopExit
ENDM
EndMessageLoop MACRO mStruct
invoke TranslateMessage, ADDR mStruct
invoke DispatchMessage, ADDR mStruct
jmp MessageLoopStart
MessageLoopExit:
ENDM
; --------------------------------------------------------
; MsgBox macro takes 2 parameters, both can be either
; literal text in quotes or addresses of zero terminated
; strings passed with "ADDR szString" where szString is
; a zero terminated string. Note that ADDR is uppercase.
;
; example : MsgBox "Greetings all",ADDR szTitle
; MsgBox ADDR szMessage,"Result"
;
; --------------------------------------------------------
MsgBox MACRO handl, TxtMsg, TxtTitle, styl
LOCAL Msg1
LOCAL Titl
If @InStr(1,<TxtMsg>,<ADDR>) eq 0
If @InStr(1,<TxtTitle>,<ADDR>) eq 0
.data
Msg1 db TxtMsg,0
Titl db TxtTitle,0
.code
invoke MessageBox,handl,ADDR Msg1,ADDR Titl,styl
EXITM
EndIf
EndIf
If @InStr(1,<TxtMsg>,<ADDR>) gt 0
If @InStr(1,<TxtTitle>,<ADDR>) eq 0
.data
Titl db TxtTitle,0
.code
invoke MessageBox,handl,TxtMsg,ADDR Titl,styl
EXITM
EndIf
EndIf
If @InStr(1,<TxtMsg>,<ADDR>) eq 0
If @InStr(1,<TxtTitle>,<ADDR>) gt 0
.data
Msg1 db TxtMsg,0
.code
invoke MessageBox,handl,ADDR Msg1,TxtTitle,styl
EXITM
EndIf
EndIf
If @InStr(1,<TxtMsg>,<ADDR>) gt 0
If @InStr(1,<TxtTitle>,<ADDR>) gt 0
invoke MessageBox,handl,TxtMsg,TxtTitle,styl
EXITM
EndIf
EndIf
ENDM
; -------------------------------------------
; put zero terminated string in .data section
; alternative to the szText MACRO
; -------------------------------------------
dsText MACRO Name, Text:VARARG
.data
Name db Text,0
.code
ENDM
; -------------------------------
; make 2 WORD values into a DWORD
; result in eax
; -------------------------------
MAKEDWORD MACRO LoWord,HiWord
mov ax, HiWord
ror eax, 16
mov ax, LoWord
ENDM
; -----------------------------
; return IMMEDIATE value in eax
; -----------------------------
retval MACRO var
IF var EQ 0
xor eax, eax ;; slightly more efficient for zero
ELSE
mov eax, var ;; place value in eax
ENDIF
ENDM
; ------------------------
; inline memory copy macro
; ------------------------
Mcopy MACRO lpSource,lpDest,len
mov esi, lpSource
mov edi, lpDest
mov ecx, len
rep movsb
ENDM
;; -----------------------------------
;; INPUT red, green & blue BYTE values
;; OUTPUT DWORD COLORREF value in eax
;; -----------------------------------
RGB MACRO red, green, blue
xor eax, eax
mov al, blue ; blue
rol eax, 8
mov al, green ; green
rol eax, 8
mov al, red ; red
ENDM
; ------------------------------------------------
; The following macro were written by Ron Thomas
; ------------------------------------------------
; Retrieves the low word from double word argument
; ------------------------------------------------
LOWORD MACRO bigword
mov eax,bigword
and eax,0FFFFh ;; Set to low word
ENDM
; ----------------------
; fast lodsb replacement
; ----------------------
lob MACRO
mov al, [esi]
inc esi
ENDM
; ----------------------
; fast stosb replacement
; ----------------------
stb MACRO
mov [edi], al
inc edi
ENDM
; -------------------------------
; pascal calling convention macro
; left to right push
; -------------------------------
Pcall MACRO name:REQ,items:VARARG
LOCAL arg
FOR arg,<items>
push arg
ENDM
call name
ENDM
; ------------------------------------------------------------------
; macro for making STDCALL procedure and API calls.
; ------------------------------------------------------------------
Scall MACRO name:REQ,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12, \
p13,p14,p15,p16,p17,p18,p19,p20,p21,p22
;; ---------------------------------------
;; loop through arguments backwards, push
;; NON blank ones and call the function.
;; ---------------------------------------
FOR arg,<p22,p21,p20,p19,p18,p17,p16,p15,p14,p13,\
p12,p11,p10,p9,p8,p7,p6,p5,p4,p3,p2,p1>
IFNB <arg> ;; If not blank
push arg ;; push parameter
ENDIF
ENDM
call name ;; call the procedure
ENDM
; ---------------------------------------------------------------------
;
; The GLOBALS macro is for allocating uninitialised data in the .DATA?
; section. It is designed to take multiple definitions to make
; allocating uninitialised data more intuitive while coding.
;
; EXAMPLE: GLOBALS item1 dd ?,\
; item2 dd ?,\
; item3 dw ?,\
; item4 db 128 dup (?)
;
; ---------------------------------------------------------------------
GLOBALS MACRO var1,var2,var3,var4,var5,var6,var7,var8,var9,var0,
varA,varB,varC,varD,varE,varF,varG,varH,varI,varJ
.data?
var1
var2
var3
var4
var5
var6
var7
var8
var9
var0
varA
varB
varC
varD
varE
varF
varG
varH
varI
varJ
.code
ENDM