Hey all,
I am glad threads like this are still around for reference and knowledge. They help a lot for my understanding my massive "fun" project that I do when I have spare time.
Anyway, I have spent a while trying to solve a MACRO problem based on ideas and code snippets from this thread. Overall, I have the general macros written but having problems getting one to work. It is the new one I just wrote tonight.
Anyway, my macro code is below with a few lines of ASM code. These are the full macros, comments and all. :icon_eek:
The macro I am having trouble with is called: IsTypeOf. It ALWAYS returns 0, according to the disassembly view through VS17 debugger. No matter what I do, I cannot seem to get it to return a 1 when the condition is true.
What am I missing. :icon_redface:
;; ============================================================================
;; TTLIB_ASM fundamental MACROS
;; ============================================================================
OPC_MEM equ < 34 >
OPC_IMM equ < 36 >
OPC_STRUC equ < 36 >
OPC_GVAR equ < 42 >
OPC_REG equ < 48 >
OPC_LVAR equ < 98 >
OPC_SVAR equ < 98 >
OPC_FN equ < 165 >
IsTypeOf MACRO OpCodeUnknown:REQ, OpCodes:VARARG
; possible OPCODEs that are valid parameters to macros that create/destory
; memory or objects will be the following for 64-bit compilation:
;
; 34: memory opcode value (ie: [r15+10h])
; 36: immediate opcode value (ie: 127, sizeof)
; 42: global address opcode value (ie: .data or .data? variable)
; 48: register opcode value (ie: rax, rsi, r11)
; 98: stack (local) opcode value (ie: [rsp+10h])
; 165: function address opcode value (ie: HeapAlloc)
FOR arg, <OpCodes>
IF .TYPE(OpCodeUnknown) EQ .TYPE(arg)
EXITM <TRUE>
ENDIF
ENDM
EXITM <FALSE>
ENDM
;; ----------------------------------------------------------------------------
;; Two macros to create an object and call the Constructor and Destructor. To
;; alloc an array or another type of memory, just use 'new' and 'del' macros.
;; ============================================================================
TTCreateObject MACRO objName:REQ, ctor:REQ
IF IsTypeOf(dtor, OPC_FN) EQ TRUE
IF IsTypeOf(objName, OPC_IMM) EQ TRUE
new objName ;; allocate memory of specified size
ELSE
.ERR <"1st parameter (obj) is not an immediate.">
ENDIF
mov rcx, rax ;; move instance object to 1st parameter
call ctor ;; call the constructor function
EXITM <rax> ;; return this$ pointer to instance
ELSE
.ERR <"2nd parameter (ctor) is not correct.">
ENDIF
EXITM <NULL>
ENDM
TTDestroyObject MACRO memPtr:REQ, dtor:REQ
IF IsTypeOf(dtor, OPC_FN) EQ TRUE
mov rcx, memPtr ;; set parameter for destructor
call dtor ;; call the destructor function
ELSE
.ERR <"Second parameter must be a function address">
ENDIF
IF IsTypeOf(memPtr, OPC_MEM,OPC_GVAR,OPC_REG,OPC_LVAR,OPC_SVAR) EQ TRUE
del memPtr ;; free the memory pointer
ELSE
.ERR < "First parameter must be a register or memory type." >
ENDIF
EXITM <>
ENDM
;; ----------------------------------------------------------------------------
;; Macro to call a function. This is an enhance call macro that will
;; call WinAPI functions, TTAPI functions, TTAPI virtual functions, and
;; finally, user defined functions - virtual or not.
;;
;; Note: When calling a function that is part of an object and has "instance"
;; data associated to the function, the first parameter (rcx) must have
;; the instance pointer.
externdef TTObject_CallVirtualFN :proc
jsr MACRO fnORid:REQ, Virtual:=<FALSE>
IFIDNI <Virtual>,<TRUE>
;; transfer the ID over to the function without destroying
;; any of the possible parameters passed through the registers.
mov rax, fnORid ; id of virtual function
call TTObject_CallVirtualFN
;; now call the virtual mapped function
call rax
ELSE
;; no virtual function to call, just call normally
call fnORid
ENDIF
ENDM
;; ----------------------------------------------------------------------------
;; Macros to allocate and destroy a memory object from the Windows Heap.
;; The memory allocation is also zeroed out upon allocation.
;; If the ctor is defined, will call the constructor for the allocated object.
;; ============================================================================
externdef G_hWinHeap :HANDLE
new MACRO s:REQ
IF IsTypeOf(s, OPC_MEM, OPC_GVAR, OPC_REG, OPC_LVAR, OPC_SVAR) EQ TRUE
mov r8, s ;; size of memory to allocate
mov rdx, (HEAP_GENERATE_EXCEPTIONS or HEAP_ZERO_MEMORY)
mov rcx, G_hWinHeap ;; handle to the process' heap
jsr HeapAlloc ;; Win32 API call
ELSE
.ERR <"Parameter is not correct type.">
ENDIF
ENDM
del MACRO m:REQ
IF IsTypeOf(s, OPC_MEM, OPC_GVAR, OPC_REG, OPC_LVAR, OPC_SVAR) EQ TRUE
mov r8, m ;; pointer to memory
xor rdx, rdx ;; no flags for HeapFree
mov rcx, G_hWinHeap ;; handle to the process' heap
jsr HeapFree ;; Win32 API call (includes space for shadow registers)
ELSE
.ERR <"Parameter is not correct type.">
ENDIF
ENDM
The ASM lines I am using for testing are the following:
mov rax, IsTypeOf(TTWinApp_Constructor, OPCODE_FUNCTION) ; should return TRUE (1)
mov rax, IsTypeOf(ttAplication.bHiColorIcons, OPC_MEM, OPC_GVAR, OPC_REG, OPC_LVAR, OPC_SVAR) ; should return TRUE (1)
mov rax, IsTypeOf(this$, OPC_IMM, OPC_FN) ; should return FALSE (0)
; actual line of code in my source file.
mov oObject.vtable, TTCreateObject(TTMap, TTMap_ctor)
Thank you all for any help with debugging/solving my mistakes.
Relvinian