📄 macros.asm
字号:
ENDM
; ********************************************************
; format a C style string complete with escape characters
; and return the offset of the result to the calling macro
; ********************************************************
cfm$ MACRO txt:VARARG ;; format C style string
LOCAL buffer,lbuf,rbuf,sln,flag1,tmp,notq
flag1 = 0
notq = 0
buffer equ <>
lbuf equ <>
rbuf equ <>
FORC char,<txt>
IFDIF <char>,<"> ;; test if 1st char is a quote
notq = 1
EXITM ;; exit with notq set to 1 if its not
ENDIF
EXITM ;; else exit with notq set to 0
ENDM
IF notq EQ 1
EXITM <txt> ;; return original arg if its not a quote
ENDIF
FORC char,<txt>
IF flag1 NE 0 ;; process characters preceded by the escape character
IFIDN <char>,<n>
buffer CATSTR buffer,<",13,10,"> ;; \n = newline
flag1 = 0
goto lpend
ENDIF
IFIDN <char>,<t>
buffer CATSTR buffer,<",9,"> ;; \t = tab
flag1 = 0
goto lpend
ENDIF
IFIDN <char>,<\>
buffer CATSTR buffer,<\> ;; \\ = \
flag1 = 0
goto lpend
ENDIF
IFIDN <char>,<q>
buffer CATSTR buffer,<",34,"> ;; \q = quote
flag1 = 0
goto lpend
ENDIF
;; ---------------------
;; masm specific escapes
;; ---------------------
IFIDN <char>,<l>
buffer CATSTR buffer,<",60,"> ;; \l = <
flag1 = 0
goto lpend
ENDIF
IFIDN <char>,<r>
buffer CATSTR buffer,<",62,"> ;; \r = >
flag1 = 0
goto lpend
ENDIF
IFIDN <char>,<x>
buffer CATSTR buffer,<",33,"> ;; \x = !
flag1 = 0
goto lpend
ENDIF
IFIDN <char>,<a>
buffer CATSTR buffer,<",40,"> ;; \a = (
flag1 = 0
goto lpend
ENDIF
IFIDN <char>,<b>
buffer CATSTR buffer,<",41,"> ;; \b = )
flag1 = 0
goto lpend
ENDIF
ENDIF
IFIDN <char>,<\> ;; trap the escape character and set the flag
flag1 = 1
goto lpend
ENDIF
buffer CATSTR buffer,<char>
:lpend
ENDM
;; ---------------------------------------------
;; strip any embedded <"",> characters sequences
;; ---------------------------------------------
buffer CATSTR buffer,<,0,0,0> ;; append trailing zeros
cpos INSTR buffer,<"",> ;; test for leading junk
IF cpos EQ 1
buffer SUBSTR buffer,4 ;; chomp off any leading junk
ENDIF
:reloop
cpos INSTR buffer,<"",>
IF cpos EQ 0 ;; if no junk left
goto done ;; exit the loop
ENDIF
lbuf SUBSTR buffer,1,cpos-1 ;; read text before junk
rbuf SUBSTR buffer,cpos+3 ;; read text after junk
buffer equ <> ;; clear the buffer
buffer CATSTR lbuf,rbuf ;; concantenate the two
goto reloop ;; loop back and try again
:done
sln SIZESTR buffer
buffer SUBSTR buffer,1,sln-4 ;; trim off tail padding
.data
tmp db buffer ;; write result to DATA section
.code
EXITM <OFFSET tmp> ;; return the DATA section OFFSET
ENDM
; ----------------------------------------------------------------------
; A macro that encapsulates GetLastError() and FormatMessage() to return
; the system based error string for debugging API functions that return
; error information with the GetLastError() API call.
; ----------------------------------------------------------------------
LastError$ MACRO
IFNDEF @@_e_r_r_o_r_@@
.data?
@@_e_r_r_o_r_@@ db 1024 dup (?)
.code
ENDIF
pushad
pushfd
invoke GetLastError
mov edi,eax
invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,
NULL,edi,0,ADDR @@_e_r_r_o_r_@@,1024,NULL
popfd
popad
EXITM <OFFSET @@_e_r_r_o_r_@@>
ENDM
; --------------------------------------------
; the following two macros are for prototyping
; direct addresses with a known argument list.
; --------------------------------------------
SPROTO MACRO func_addr:REQ,arglist:VARARG ;; STDCALL version
LOCAL lp,var
.data?
func_addr dd ?
.const
var typedef PROTO STDCALL arglist
lp TYPEDEF PTR var
EXITM <equ <(TYPE lp) PTR func_addr>>
ENDM
CPROTO MACRO func_addr:REQ,arglist:VARARG ;; C calling version
LOCAL lp,var
.data?
func_addr dd ?
.const
var typedef PROTO C arglist
lp TYPEDEF PTR var
EXITM <equ <(TYPE lp) PTR func_addr>>
ENDM
; ------------------------------------------------------
; turn stackframe off and on for low overhead procedures
; ------------------------------------------------------
stackframe MACRO arg
IFIDN <on>,<arg>
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
ELSEIFIDN <off>,<arg>
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
ELSE
echo -----------------------------------
echo ERROR IN "stackframe" MACRO
echo Incorrect Argument Supplied
echo Options
echo 1. off Turn default stack frame off
echo 2. on Restore stack frame defaults
echo SYNTAX : frame on/off
echo -----------------------------------
.err
ENDIF
ENDM
; ----------------------------------------------------------------
; invoke enhancement. Add quoted text support to any procedure
; or API call by using this macro instead of the standard invoke.
; LIMITATION : quoted text must be plain text only, no ascii
; values or macro reserved characters IE <>!() etc ..
; use SADD() or chr$() for requirements of this type.
; ----------------------------------------------------------------
fn MACRO FuncName:REQ,args:VARARG
arg equ <invoke FuncName> ;; construct invoke and function name
FOR var,<args> ;; loop through all arguments
arg CATSTR arg,<,reparg(var)> ;; replace quotes and append arg
ENDM
arg ;; write the invoke macro
ENDM
; ------------------------------------------------
; Function return value version of the above macro
; ------------------------------------------------
rv MACRO FuncName:REQ,args:VARARG
arg equ <invoke FuncName> ;; construct invoke and function name
FOR var,<args> ;; loop through all arguments
arg CATSTR arg,<,reparg(var)> ;; replace quotes and append arg
ENDM
arg ;; write the invoke macro
EXITM <eax> ;; EAX as the return value
ENDM
; ---------------------------------------------------
; The two following versions support C style escapes.
; ---------------------------------------------------
fnc MACRO FuncName:REQ,args:VARARG
arg equ <invoke FuncName> ;; construct invoke and function name
FOR var,<args> ;; loop through all arguments
arg CATSTR arg,<,cfm$(var)> ;; replace quotes and append arg
ENDM
arg ;; write the invoke macro
ENDM
rvc MACRO FuncName:REQ,args:VARARG
arg equ <invoke FuncName> ;; construct invoke and function name
FOR var,<args> ;; loop through all arguments
arg CATSTR arg,<,cfm$(var)> ;; replace quotes and append arg
ENDM
arg ;; write the invoke macro
EXITM <eax> ;; EAX as the return value
ENDM
comment * ------------------------------------------
jmp_table is used for arrays of label addresses
MASM supports writing the label name directly
into the .DATA section.
EXAMPLE:
jmp_table name,lbl1,lbl2,lbl3,lbl4
------------------------------------------ *
jmp_table MACRO name,args:VARARG
.data
align 4
name dd args
.code
ENDM
; *******************
; DATA DECLARATIONS *
; *******************
; -------------------------------------
; initialised GLOBAL value of any type
; -------------------------------------
GLOBAL MACRO variable:VARARG
.data
align 4
variable
.code
ENDM
; --------------------------------
; initialised GLOBAL string value
; --------------------------------
STRING MACRO variable:REQ,args:VARARG
.data
variable db args,0
align 4
.code
ENDM
; --------------------------------
; initialise floating point vaues
; --------------------------------
FLOAT4 MACRO name,value
.data
align 4
name REAL4 value
.code
ENDM
FLOAT8 MACRO name,value
.data
align 4
name REAL8 value
.code
ENDM
FLOAT10 MACRO name,value
.data
align 4
name REAL10 value
.code
ENDM
; **********************************************************
; function style macros for direct insertion of data types *
; **********************************************************
FP4 MACRO value
LOCAL vname
.data
align 4
vname REAL4 value
.code
EXITM <vname>
ENDM
FP8 MACRO value
LOCAL vname
.data
align 4
vname REAL8 value
.code
EXITM <vname>
ENDM
FP10 MACRO value
LOCAL vname
.data
align 4
vname REAL10 value
.code
EXITM <vname>
ENDM
; --------------------------------------------
; FLD does not accept immediate operands. These
; macros emulate loading an immediate value by
; loading the value into the .DATA section.
; EXAMPLE : fld8 1234.56789
; --------------------------------------------
fld4 MACRO fpvalue
LOCAL name
.data
name REAL4 fpvalue
align 4
.code
fld name
ENDM
fld8 MACRO fpvalue
LOCAL name
.data
name REAL8 fpvalue
align 4
.code
fld name
ENDM
fld10 MACRO fpvalue
LOCAL name
.data
name REAL10 fpvalue
align 4
.code
fld name
ENDM
; --------------------------------------------
; **********************************************
; The original concept for the following macro *
; was designed by "huh" from New Zealand. *
; **********************************************
; ---------------------
; literal string MACRO
; ---------------------
literal MACRO quoted_text:VARARG
LOCAL local_text
.data
local_text db quoted_text,0
align 4
.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
; -----------------------------------------------------
; string address embedded directly in the code section
; -----------------------------------------------------
CADD MACRO quoted_text:VARARG
LOCAL vname,lbl
jmp lbl
vname db quoted_text,0
align 4
lbl:
EXITM <ADDR vname>
ENDM
; --------------------------------------------------
; Macro for placing an assembler instruction either
; within another or within a procedure call
; --------------------------------------------------
ASM MACRO parameter1,source
LOCAL mnemonic
LOCAL dest
LOCAL poz
% poz INSTR 1,<parameter1>,< > ;; get the space position
mnemonic SUBSTR <parameter1>, 1, poz-1 ;; get the mnemonic
dest SUBSTR <parameter1>, poz+1 ;; get the first argument
mnemonic dest, source
EXITM <dest>
ENDM
; ------------------------------------------------------------
; Macro for nesting function calls in other invoke statements
; ------------------------------------------------------------
FUNC MACRO parameters:VARARG
invoke parameters
EXITM <eax>
ENDM
; -------------------------------------------
; Pseudo mnemonics.
; These macros emulate assembler mnemonics
; but perform higher level operations not
; directly supported by the instruction set
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -