How can I convert this lines from MASM to FASM
Can some body please tell me how to convert this lines from MASM to FASM and can some body explain me what do they mean?

mov eax, pPicture
push eax
mov eax,
call .IPicture.Render

Thanks alot for your help I'm new on Assembly :rolleyes:
Posted on 2003-02-17 22:12:47 by alonso
This is a COM call to a virtual function.

Its not Masm specific. It is M$ OLE specific.

Your source is

    [*]Taking a pointer of an interface structure (in memory).
    [*]Pushing the 'this interface' object parameter so the render method will operate on the object/interface that called in the first place.
    [*]Then exctracting the virtual function table pointer from the interface structure. Its always the first DWORD of any Interface.
    [*]Then calling the 'Render' function pointer located in the virtual function table. All the functions have lables such as 'Render' cause they are actualy a stucture of DWORD function pointers. One function pointer to one structure name. So effectively the call is doing something like "call " where 12 (hypothetically) could be the third function pointer called "Render" (3 * 4bytes = 12). I dont know what the *real* offset is for Render in this interface. But you get the idea.

    Well there you go. I dont use FASM, never have, so i cant help you much more than this. (However, i would be surprised if FASM can't handly what you have posted. Its pretty simple operations).

    :alright:
    NaN
Posted on 2003-02-17 22:51:04 by NaN
Thanks for your help NaN

Let me see if I got this right!

You say that you can Use an API call to get a group of pointers to certain function and this function have subfunctions, so you when you use Call .IPicture.Render your calling a subrutine which IPicture.Render has the address where that subroutine starts, if that is the case why don't just use IPicture.Render not

Sincerely:
Alonso Murillo


This is a COM call to a virtual function.

Its not Masm specific. It is M$ OLE specific.

Your source is

    [*]Taking a pointer of an interface structure (in memory).
    [*]Pushing the 'this interface' object parameter so the render method will operate on the object/interface that called in the first place.
    [*]Then exctracting the virtual function table pointer from the interface structure. Its always the first DWORD of any Interface.
    [*]Then calling the 'Render' function pointer located in the virtual function table. All the functions have lables such as 'Render' cause they are actualy a stucture of DWORD function pointers. One function pointer to one structure name. So effectively the call is doing something like "call " where 12 (hypothetically) could be the third function pointer called "Render" (3 * 4bytes = 12). I dont know what the *real* offset is for Render in this interface. But you get the idea.

    Well there you go. I dont use FASM, never have, so i cant help you much more than this. (However, i would be surprised if FASM can't handly what you have posted. Its pretty simple operations).

    :alright:
    NaN
Posted on 2003-02-19 07:23:12 by alonso
no, there is no API's in this picture.. only memory, memory pointers, and function pointers. Here is another stab at putting the picture together. I made up fake memory addresses and function pointers, but the intent is how it actually works
(hypothetical picture here)


Interface in memory: pIPicture == 0062A2F4h
-----------------------------------------
0062A2F4h : 0077E304h (vtable pointer)
: and
: other
: Interface
: specific
: memory
: Variables

Virtual Function pointer table for all
interface methods/property functions == 0077E304h
-------------------------------------------------

0077E304h : 00123456h (function #1 pointer)
: 00234567h (function #2 pointer)
: 00345678h (Render function pointer)
: 00456789h (function #4 pointer)
: etc.
: etc.


The IPicture Interface structure could be:

IPicture STRUC
fucntion#1 dd ?
fucntion#2 dd ?
Render dd ?
function#3 dd ?
etc.
etc.
IPicture ENDS

So by getting an interface pointer (0062A2F4h),

mov eax, 0062A2F4h

And then getting the vtable pointer,

mov eax, [eax] ; (eax == 0077E304h)

And then applying a structure to look up the
"Render function pointer"

mov edx, [eax].IPicture.Render
;; Edx now has 00345678h

Always push the interface pointer, so the function
will operate on interface specific memory (as
indicated above in the interface memory map).

push 0062A2F4h

Now call the fucntion that was looked up to do
the render operation on the interface that
called it.

call edx


:NaN:
Posted on 2003-02-20 00:35:08 by NaN
wouldnt it look something like this



mov eax, [pPicture]
push eax
mov eax, [eax]

virtual at eax
eax IPicture
end virtual

call [eax.Render]



i've never used this but this mite work.
Posted on 2003-02-20 03:51:14 by keyoke
Thanks,

Nan for your patience and help, sorry to Contradict you but there is an API call involve on this.


IPicture STRUCT
; IUnknown methods
QueryInterface DWORD ?
AddRef DWORD ?
Release DWORD ?
; IPicture methods
get_Handle DWORD ?
get_hPal DWORD ?
get_Type DWORD ?
get_Width DWORD ?
get_Height DWORD ?
Render DWORD ?
set_hPal DWORD ?
get_CurDC DWORD ?
SelectPicture DWORD ?
get_KeepOriginalFormat DWORD ?
put_KeepOriginalFormat DWORD ?
PictureChanged DWORD ?
SaveAsFile DWORD ?
get_Attributes DWORD ?
IPicture ENDS

invoke OleLoadPicture, pStream, NULL, TRUE, ADDR IID_IPicture, ADDR pPicture

; ok, now we have our bitmap mounted onto our temporary DC, let's blit to it
; (IPicture)pPicture::Render(hdc, x, y, cx, cy, \
; xpos_himetric, ypos_himetric, \
; xsize_himetric, ysize_himetric, *rectBounds)
push NULL ; *rectBounds
push neghmHeight
push hmWidth
push hmHeight
push 0
push dwHeight
push dwWidth
push 0
push 0
push tempDC
mov eax, pPicture
push eax
mov eax, [eax]
call [eax].IPicture.Render


What I'm asking is why can we use mov eax,IPicture.Render instead of mov eax, pPicture, because IPicture.Render should have a pointer to the sub that we want to call.

Thanks alot again.

Sincerely, Alonso Murillo.

.:EDIT:. Added code blocks for readablility
Posted on 2003-02-20 08:43:54 by alonso
Because IPicture is not data. It is a data format or layout.
It is also a data type.
You must allocate (define) data of type IPicture, or use a pointer of type IPicture.
MASM allows you to force the type of a register-based address with the .IPicture notation.
Posted on 2003-02-20 21:20:29 by tenkey
Originally posted by alonso

What I'm asking is why can we use mov eax,IPicture.Render instead of mov eax, pPicture, because IPicture.Render should have a pointer to the sub that we want to call.


Sure, if i only passed pPicture technically the computer would have all it needs. But the computer is not a mind-reader. I still has not IDEA what your intending when you throw an interface at it.

Its like saying.. "Call some function, and get it right". You have to TELL it what function you want to call from the interface. You say "here is my interface, with specific data stored in it", and then you look up the function you want to use on your data and say "Now call this 'Render' function you happend to have in your interface, you will notice i pushed on the stack all the parameters you will need for this function, Mr. CPU".

I cant explain this anymore. I've done so from a memory map side, software side, and now an "Im talking to my computer" side. If your still having problems with this concept you should re-read this thread a couple of times.

:alright:
NaN
Posted on 2003-02-21 03:25:26 by NaN
Furthermore,

Consider this. What if the 'Render' function also needs to use the 'get_CurDC' function as part of its operation. I need to give it the interface itself as the first param of any COM call, so that it is standardized and every COM function will know this fact. If it needs to call something specific to itself, it will know the first param is the "THIS" interface pointer, and can look up other fucntions it needs from its vtable.

The next two lines "Mov eax, " and "Call .IPicture.Render" is telling the CPU to call the specific Render function as i mentioned above.

:NaN:
Posted on 2003-02-21 03:32:21 by NaN
I also noticed your using the C++ definition as a guide:
; (IPicture)pPicture::Render(hdc, x, y, cx, cy,                            \

; xpos_himetric, ypos_himetric, \
; xsize_himetric, ysize_himetric, *rectBounds)


This is correct for C++, as the C++ compiler does 'extra' work your not seing here. There is *ALWYAS* a "THIS INTERFACE" pointer as the first param to any method call from a COM interface. Since the guys who wrote C++ know this, they decided to hide this extra param from you. After all it it would be extra typing that can be easily automated.

In assembly this is not true. MASM assumes NOTHING. You need to fit the formate exactly and do the extra that C++ would have done for you. In this case the MASM equivalent would be:


; (IPicture)pPicture::Render( [color=red]IPicture * pPicture,[/color] hdc, x, y, cx, cy, \
; xpos_himetric, ypos_himetric, \
; xsize_himetric, ysize_himetric, *rectBounds)
    push NULL

push neghmHeight
push hmWidth
push hmHeight
push 0
push dwHeight
push dwWidth
push 0
push 0
push tempDC
[color=red] mov eax, pPicture
push eax[/color]
And the C++ call:
    [color=red]pPicture->Render [/color]( hdc, x, y, cx, cy, xp, yp, xs, ys, NULL ) 


Would become:


[color=red] mov eax, pPicture
mov eax, [eax]
call [eax + 32][/color] ; Since the "Render" method is after the 8th dword


If your lost why the +32 thing, i refer you to Here...

There you go. All the pieces are before you. I leave it to you to consume and understand.
:alright:
NaN
Posted on 2003-02-21 03:47:23 by NaN
You can use the "comcall" macro for it, it's included in the DDraw example in the FASMW package:


macro comcall object,proc,[arg]
{ common
if ~ arg eq
reverse
pushd arg
common
end if
mov eax,[object#.#handle]
push eax
mov eax,[eax]
call [eax+object#.#proc] }

You need also the following definitions:


struc IPicture
{
.handle dd ?
virtual at 0
.QueryInterface dd ?
.AddRef dd ?
.Release dd ?
.get_Handle dd ?
.get_hPal dd ?
.get_Type dd ?
.get_Width dd ?
.get_Height dd ?
.Render dd ?
.set_hPal dd ?
.get_CurDC dd ?
.SelectPicture dd ?
.get_KeepOriginalFormat dd ?
.put_KeepOriginalFormat dd ?
.PictureChanged dd ?
.SaveAsFile dd ?
.get_Attributes dd ?
end virtual
}

pPicture IPicture

and so your code can become:


comcall pPicture,Render
Posted on 2003-02-21 07:43:03 by Tomasz Grysztar
Thank you very much Privalov for your help, that's what just needed!
Posted on 2003-02-21 10:16:46 by alonso
Well you can't say i didnt try to teach a man to fish ;P

:alright:
NaN
Posted on 2003-02-21 16:56:25 by NaN
BTW: How would you use this calling convention if the pPicture interface was dynamically returned into EAX?

How would FASM know that the value in eax is actually a pPicture pointer with out telling it at compile time?

:NaN:
Posted on 2003-02-21 22:04:27 by NaN