Any ideas how to avoid using a register? My app has the start addresses of procedures in a table (TheAddress), and I'd like to use invoke on the equivalent of offset TheAddress[index*DWORD]
include \masm32\include\masm32rt.inc
MyType typedef PROTO C :DWORD, :DWORD ; just a proc with two args
.data
TheAddress dd MyTest, My2ndTest, My3rdproc
.code
start:
if 0
mov edx, offset TheAddress
invoke MyType ptr [edx], chr$("text"), chr$("title") ; works
elseif 0
xor edx, edx
invoke MyType ptr TheAddress[edx], chr$("text"), chr$("title") ; works but needs edx
elseif 1
; ML.exe executes and fails miserably
; JWasm Error A2071: Invalid operand size for instruction
invoke MyType ptr TheAddress[0], chr$("text"), chr$("title")
; under the hood: push arg2, push arg1, call TheAddress
endif
inkey "OK"
exit
MyTest proc C arg1:DWORD, arg2:DWORD
MsgBox 0, arg1, arg2, MB_OK
ret
MyTest endp
end start
here's a post by qWord
http://masm32.com/board/index.php?topic=1286.msg12718#msg12718 (http://masm32.com/board/index.php?topic=1286.msg12718#msg12718)
he uses TYPEDEF and PROTO together - a new one on me
is that what you mean ?
here's another method by Vortex that i reference once in a while
http://www.masmforum.com/board/index.php?topic=11772.msg89003#msg89003 (http://www.masmforum.com/board/index.php?topic=11772.msg89003#msg89003)
i guess typedef and proto is nothing new
if you look at the ArgCount macro, it does the same
ArgCount MACRO number
LOCAL txt
txt equ <typedef PROTO :DWORD>
REPEAT number - 1
txt CATSTR txt,<,:DWORD>
ENDM
EXITM <txt>
ENDM
pr0 typedef PROTO
pr1 ArgCount(1)
pr2 ArgCount(2)
pr3 ArgCount(3)
;and so on
Dave,
qWord's version seems identical to what I tested already.
The other one looks a bit 'hackish':
func db 0FFh,025h ; define a jump entry
dd pFunc
... and I guess you would have to insert the two bytes for every address in the table, which is a bit impractical.
Thanks anyway - I will keep testing.
yes - but i remember looking at that when i was working on the dereferencing routine :P
here's one from Yves....
TestProc PROTO :DWORD
Pfunction TYPEDEF PROTO :DWORD
Ffunction TYPEDEF PTR Pfunction
function TEXTEQU <Ffunction ptr ADRfunction>
.data
ADRfunction dd TestProc
.code
.....
invoke function,NULL
Quote from: jj2007 on February 05, 2013, 02:21:37 AM
qWord's version seems identical to what I tested already.
I doubt that, because qword's sample is the way to go:
He defines 2 things, a
function type and a
function pointer type, while in your sample I'n able to see a definition of a function type only.
well - the point is, it still uses a register
i think Yves' example demonstrates what he wants
i am learning stuff, this morning - not that old, after all 8)
Thanks, Dave & japheth :t
TheAddress dd MyTest
...
tmp typedef PROTO C :DWORD, :DWORD
MyType typedef ptr tmp
invoke MyType ptr TheAddress, chr$("text"), chr$("title") ; works fine
@Dave: It works also without a register. This is some stuff I found under the hood before japheth's post.
works fine but edx trashed (and I can't zero it before pushing!!)
xor edx, edx
invoke MyType ptr TheAddress[edx], chr$("text"), chr$("title") ; works but needs edx
; 00401013 . 68 0C404000 push offset ??001A ; ASCII "title"
; 00401018 . 68 04404000 push offset ??0019 ; ASCII "text"
; 0040101D . FF92 00404000 call dword ptr [edx+TheAddress]
manually corrected in Olly, works fine:
; 00401013 . 68 0C404000 push offset ??001A ; ASCII "title"
; 00401018 . 68 04404000 push offset ??0019 ; ASCII "text"
; 0040101D FF15 00404000 call dword ptr [TheAddress]
invoke MyType ptr TheAddress[0], chr$("text"), chr$("title") ; crashes
; 00401013 . 68 0C404000 push offset ??001A ; ASCII "title"
; 00401018 . 68 04404000 push offset ??0019 ; ASCII "text"
; 0040101D . E8 DE2F0000 call TheAddress
; 00401022 ? 83C4 08 add esp, 8
Hi Jochen, probably this suits your needs:
include \masm32\include\masm32rt.inc
.686
.mmx
.xmm
.data
invoketable dd offset proc1
dd offset proc2
dd offset proc3
.code
proc1 proc dwdword
invoke crt_printf,CTXT("proc1, %d",13,10),dwdword
ret
proc1 endp
proc2 proc dwdword
invoke crt_printf,CTXT("proc2, %d",13,10),dwdword
ret
proc2 endp
proc3 proc dwdword
invoke crt_printf,CTXT("proc3, %d",13,10),dwdword
ret
proc3 endp
stdcall@4 typedef PROTO stdcall :DWORD
stdcall@4@ptr typedef ptr stdcall@4
start proc
invoke stdcall@4@ptr ptr invoketable,999
invoke stdcall@4@ptr ptr invoketable[0],111
invoke stdcall@4@ptr ptr invoketable[4],222
invoke stdcall@4@ptr ptr invoketable[8],333
mov ebx,3
@@:
invoke stdcall@4@ptr ptr invoketable[ebx*4-4],ebx
dec ebx
jnz @B
invoke crt__getch
invoke crt_exit,0
start endp
end start
proc1, 999
proc1, 111
proc2, 222
proc3, 333
proc3, 3
proc2, 2
proc1, 1
Quote from: Antariy on February 05, 2013, 10:25:16 AM
Hi Jochen, probably this suits your needs:
Thanks, Alex. Yes that would work, too, but I needed variable args. So I settled for this in the end:
MacName$ macro args:VARARG
LOCAL tmptype, gslType
tmptype typedef PROTO C gslArgsLocal$ ; e.g. :DWORD, :RECT, :DWORD...
gslType typedef PTR tmptype
invoke gslType PTR ProcTable[curMac*DWORD], args
Hi Jochen,
Here is my solution :
include \masm32\include\masm32rt.inc
include invoke.inc
.data
FuncTable dd 0,
OFFSET MessageBox,
OFFSET ExitProcess
_title db 'Hello',0
msg db 'Function table',0
.code
start:
_invoke FuncTable[1*DWORD],0,ADDR msg,ADDR _title,MB_OK
_invoke FuncTable[2*DWORD],0
END start
Hi Erol,
a very good solution. :t
Gunther
Quote from: Vortex on February 06, 2013, 05:48:57 AM
Hi Jochen,
Here is my solution :
Thanks a lot, Erol, I will study it :t