; types.inc ; A set of macros for specifying type ; information about MASM variables. ifndef aoaTypes_inc aoaTypes_inc = 1 ; types$len- ; ; A private macro that returns the length of the ; argument. types$len macro v:req exitm %lengthof &v endm ; type$macro- ; ; A helper macro for the type-specific macros that ; handles most of the work for those macros. See ; the individual macros that invoke type$macro ; for more information: type$macro macro v:req, tNam:req, tSiz:req, elms local elements ; Define: ; "id$type" (where "id" is the name passed ; as the "v" argument), ; ; "id$tSize" (the type size, which is the size of one ; element if this is an array), and ; ; "id$name" that holds the name of the variable. &v&$type textequ <&tNam> &v&$tSize textequ <&tSiz> &v&$name textequ <&v> ; The elms (elements) field in the type macros ; is optional. If it it absent, assume the ; declaration is part of one of the following: ; ; A static data declaration in some segment, e.g., ; ; byte_t(b) byte 16 dup (?) ; ; A parameter declaration in a proc statement, e.g., ; ; someProc proc int32_t(parm):dword ; ; A local variable declaration in a proc, e.g., ; ; someProc proc ; local uns32_t(array)[16]:dword ifb <&elms> ; Compute the number of array elements using the ; usual MASM function. This calls types$len to ; compute the element length of argument v: &v&$elems textequ ; Compute the size of the entire array (elements ; times type size): &v&$size textequ <&v&$tSize*types$len(&v)> ; If the elms operand is non-blank, then the ; macro's invoker has explicitly specified the ; number of array elements. This is typically ; used for declarations like the following: ; ; word_t(myArray,10) textequ <[rbp-16-10*2]> ; ; (declares a 10-element word array when not ; using MASM HLL-like local declarations). else ;elms operand is not blank ;; If zero elements, force to 1: elements = elms + ((elms eq 0) and 1) &v&$elems textequ %elements &v&$size textequ <&v&$tSize*elements> endif exitm <&v> endm ; Type macros. ; ; Use these macros to process identifiers in variable ; declarations appearing in your program. A macro ; invocation of the form "type_t(id)" where "type_t" ; represents one of these macros and "id" represents ; an identifier will return "id" as its text ; (effectively removing the macro invocation from the ; line) and also set up several global symbols the ; assembly language code can use to obtain information ; about the declaration. ; ; The typical usage of these macros is the following: ; ; In a data segment: ; ; byte_t(b) byte ? ; word_t(w) word 16 dup (?) ; ; In a procedure parameter declaration: ; ; someProc proc dword_t(parm1):dword, \ ; uns64_t(parm2):qword, \ ; real8_t(parm3):real8 ; ; In the local variable declarations of a procedure: ; ; someProc proc ; local qword_t(ptrVar):qword ; local byte_t(buf)[64]:byte ; ; You can also use these type macros with manually- ; defined memory objects (using text equates) as ; follows: ; ; int32_t(i,0) textequ ; ; The second macro argument specifies the number of ; array elements (if any, use 0 if this is a scalar ; object). ; ; Invoking this macro produces the following symbols: ; ; id$type - A text string containing the actual type ; (e.g., ) ; ; id$tSize- A text string containing the size of ; the underlying data type (size of an ; element if it's an array). For example, ; if id$type is , then id$tSize ; will be <4>. ; ; id$elems- A text string that expands to an ; expression specifying the number ; of array elements associated with ; this symbol. If the symbol is not ; an array type, this value will be ; <1>. ; ; id$size- A text string containing an expression ; that evaluates to the full size of ; this object in memory. If an array, ; this is all the bytes in the array; ; if not an array, this value should ; match id$tSize. ; real4_t macro v:req, elems exitm type$macro(&v, real4, 4, <&elems>) endm real8_t macro v:req, elems exitm type$macro(&v, real8, 8, <&elems>) endm real10_t macro v:req, elems exitm type$macro(&v, real10, 10, <&elems>) endm int64_t macro v:req, elems exitm type$macro(&v, int64, 8, <&elems>) endm int32_t macro v:req, elems exitm type$macro(&v, int32, 4, <&elems>) endm int16_t macro v:req, elems exitm type$macro(&v, int16, 2, <&elems>) endm int8_t macro v:req, elems exitm type$macro(&v, int8, 1, <&elems>) endm uns64_t macro v:req, elems exitm type$macro(&v, uns64, 8, <&elems>) endm uns32_t macro v:req, elems exitm type$macro(&v, uns32, 4, <&elems>) endm uns16_t macro v:req, elems exitm type$macro(&v, uns16, 2, <&elems>) endm uns8_t macro v:req, elems exitm type$macro(&v, uns8, 1, <&elems>) endm qword_t macro v:req, elems exitm type$macro(&v, qword, 8, <&elems>) endm dword_t macro v:req, elems exitm type$macro(&v, dword, 4, <&elems>) endm word_t macro v:req, elems exitm type$macro(&v, word, 2, <&elems>) endm byte_t macro v:req, elems exitm type$macro(&v, byte, 1, <&elems>) endm bool_t macro v:req, elems exitm type$macro(&v, bool, 1, <&elems>) endm char_t macro v:req, elems exitm type$macro(&v, char, 1, <&elems>) endm ; Note: string_t and wstring_t are pointers to a string type. string_t macro v:req, elems exitm type$macro(&v, string, 8, <&elems>) endm wstring_t macro v:req, elems exitm type$macro(&v, wstring, 8, <&elems>) endm ; ptr_t is a generic pointer type ptr_t macro v:req, elems exitm type$macro(&v, ptr, 8, <&elems>) endm ; Some useful macros for testing type information ; isType(id, type)- ; ; Returns true if "id" is declared as a type ; and is of type "type". Returns false if "id" ; is not a declared type or the type is not ; "type". isType macro v:req, t:req ; If id$type is not defined, this is not a type-defined ; symbol; so, return false: ifndef &v&$type exitm <0> endif ; If the id$type is defined, see if ; it is equal the the parameter type "t": ifidn &v&$type,<&t> exitm <1> endif exitm <0> endm ; isArray(id, type)- ; ; Returns true if "id" is declared as a type ; and has 2 or more array elements (scalars ; have 1 elements; if the user declares an ; array with a single element, this macro ; treats it as a scalar). isArray macro v:req, t:req ; If id$type is not defined, this is not a type-defined ; symbol; so, return false: ifndef &v&$elems exitm <0> endif ; If the id$elems is defined, see if ; it is greater than 1 if &v&$type gt 1 exitm <1> endif exitm <0> endm ; Thunk type: thunk_t struct environment qword ? procedure qword ? thunk_t ends ; Enumerated data type ; ; usage: ; enum list-of-identifers enum macro enumList:vararg local item, value value = 0 for item, item = value value = value + 1 endm endm endif ;aoaTypes_inc