News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

invoke with typedef problem

Started by jj2007, February 05, 2013, 01:29:03 AM

Previous topic - Next topic

jj2007

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

dedndave

here's a post by qWord
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 ?

dedndave


dedndave

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

jj2007

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.

dedndave

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


japheth

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.


dedndave

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)

jj2007

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

Antariy

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


jj2007

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


Vortex

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

Gunther

Hi Erol,

a very good solution.  :t

Gunther
You have to know the facts before you can distort them.

jj2007

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