I have this code which I think is from C.



SetRect(&rc, 0, 0, rect->right-rect->left, rect->bottom-rect->top);
SetWindowOrgEx(hdc, -rect->left, -rect->top, &pt);


How I can change this two lines that MASM will know what to do?

I have the source in ASM, but to rewrite it from ASM dump,
seems to me a very primitive way. Please note as well
the minus sign in front of rect.

Thanks for any help.

forge
Posted on 2001-11-23 06:55:24 by forge
 SetRect(&rc, 0, 0, rect->right-rect->left, rect->bottom-rect->top);

SetWindowOrgEx(hdc, -rect->left, -rect->top, &pt);


-> is the c operator for indirectly referencing structure/union members.
& is the address of operator

rect is a pointer to a structure ...four of the structure members are left ,right, top and bottom. this line passes the width and height of a rectangle by width=(rect->right-rect->left), height=(rect->bottom-rect->top). these values are contained in a structure of type RECT

//the c declares for the variables would be something like:


main()
{
struct RECT {
left;
top;
right;
bottom;
}myrect;

Struct RECT *rect

rect=&myrect;

}


From what i said above then

rect->bottom ==myrect.bottom
rect->top==myrect.top
etc

and -rect->left ==-(myrect.left)


[U]C masm equivalent[/U]
&rc addr rc
rect->left (RECT ptr[eax].left); if eax is a RECT pointer
-rect->left mov ecx,(RECT ptr[eax]).left
neg ecx
rect->bottom-rect->top mov ecx,(RECT ptr[eax]).bottom
mov edx,(RECT ptr[eax]).top
sub ecx,edx


i hope that helps
note that RECT is a structure defined in windows.inc
the Martial
Posted on 2001-11-23 08:08:43 by MArtial_Code
I think this'll do it (not in the normal MASM way), but I am assuming SetRect doesn't effect the contects of the rect variable.



lea eax, pt ; Can replace these two lines with OFFSET if
push eax ; var is not on the stack (local)
; push OFFSET pt

mov eax, rect
mov ecx, RECT ptr[eax].top
neg ecx
mov edx, RECT ptr[eax].left
neg edx

push ecx
push edx
push hdc

add ecx, RECT ptr[eax].bottom
add edx, RECT ptr[eax].right
push ecx
push edx
push 0
push 0
lea eax, rc ; Can replace these two lines with OFFSET if
push eax ; var is not on the stack (local)
; push OFFSET rc

call SetRect
call SetWindowOrgEx


Its kind of messy though, and much more difficult to follow than a more obvious way of doing it (but it avoids recalculation of "-rect->left" and "-rect->top" values).
To be honest its an optimisation at the expense of clarity where an optimisation is unnecessary!

Mirno
Posted on 2001-11-23 08:36:34 by Mirno
What about something like:

............
.DATA?
rc RECT <>
pt POINT <>
............

.CODE

...........

;//SetRect(&rc, 0, 0, rect->right-rect->left, rect->bottom-rect->top);
mov .left,0
mov .top,0
mov eax,.right
mov edx,.left
neg edx
add eax,edx
mov .right,eax
mov eax,.bottom
mov ecx,.top
neg ecx
add eax,ecx
mov .bottom,eax
;//SetWindowOrgEx(hdc, -rect->left, -rect->top, &pt)
invoke SetWindowOrgEx,,edx,ecx,ADDR pt

........


Random
Posted on 2001-11-23 10:08:29 by random
Hi,
and thanks to MArtial_Code,Mirno and random.

You definitely know what you are talking about, but
I think that my question was not so clear.
I asked: What Masm can and can't do?
Below is a complete picture.
The source is in C and below is the exact disassembly.
It will assemble without any problem, but the assembly code
is so primitive. I think that MASM-6.15 should be able to
do it a bit better.
The Compiler can do it in 4 lines and produce a not so bad code.
I just wonder how many lines one has to write for MASM ?
In here are 35 lines.
How could I change CALL into INVOKE.
Perhaps the only way is to use more registers and not
only eax and esi.
Does the compiler know only these registers?
-----------------------------------------------------------


// Draw the specified metafile

static void DrawMetaFile(HDC hdc, HENHMETAFILE hemf, RECT *rect)
{
RECT rc;
POINT pt;


SetRect(&rc, 0, 0, rect->right-rect->left, rect->bottom-rect->top);
SetWindowOrgEx(hdc, -rect->left, -rect->top, &pt);
PlayEnhMetaFile(hdc, hemf, &rc);
SetWindowOrgEx(hdc, pt.x, pt.y, 0);
}

-----------------------------------------------------------


DrawMetaFile proc hdc :DWORD, hemf:DWORD, rect:DWORD

LOCAL rc :RECT
LOCAL pt :POINT

push esi

mov esi, rect
mov eax, [esi+0Ch] ; rect->bottom
sub eax, [esi+4] ;-rect->top
push eax
mov eax, [esi+8] ; rect->right
sub eax, [esi] ;-rect->left
push eax
push 0
lea eax, rc ; ADDR rc
push 0
push eax
call SetRect ; ADDR rc,xLeft, yTop, xRight, yBottom
lea eax, pt
push eax ; ADDR pt
mov eax, [esi+4] ; rect->top
neg eax ;-rect->top
push eax ;-rect->top
mov eax, [esi] ; rect->left
mov esi, dword ptr SetWindowOrgEx ; imp
neg eax
push eax ;-rect->left
push hdc
call esi ;SetWindowOrgEx , hdc, x-origin, y-origin, ADDR pt

lea eax, rc ; ADDR rc
push eax
push hemf ; handle to an enhanced metafile
push hdc
call PlayEnhMetaFile ; hdc, hemf, ADDR rc

push 0
push pt.y
push pt.x
push hdc
call esi ;SetWindowOrgEx , hdc, x-origin, y-origin, null

pop esi


Thanks again.
Posted on 2001-11-24 04:39:38 by forge
forge,

It depends if you need to preserve the values in the RECT that is passed to the procedure. If you don't, you can bypass the "SetRect" function to save some code and use the passed structure directly.

Regards,

hutch@movsd.com
Posted on 2001-11-24 04:56:21 by hutch--
The last two can be changed to:
invoke PlayEnhMetaFile,hdc,hemf,ADDR rc

invoke pr4 PTR esi,hdc,pt.x,pt.y,0 ;SetWindowOrgEx
But the others are too mixed up - that's the bad thing about INVOKE. :) You are right - MASM certainly has it's limitations, but then so does the compiler - as you see above. ;)
Posted on 2001-11-24 05:02:44 by bitRAKE
Thanks hutch--

I want to keep the code unchanged.
I just want to write it for Masm in most appropriate way.
For instance to write uses esi instead of push esi - pop esi.
Posted on 2001-11-24 05:09:58 by forge
Thanks bitRAKE I can't agree with you more.


IMO below is the shortest code MASM could understand and interpret.
It is 12 lines long as opposed to 4 lines in C.
Please correct me if I'm wrong as this is the best I can do.



DrawMetaFile PROTO :DWORD,:DWORD,:DWORD ;3 para hdc hemf rect

DrawMetaFile proc uses esi hdc :DWORD, hemf:DWORD, rect:DWORD

LOCAL rc :RECT
LOCAL pt :POINT

mov eax, rect.bottom
sub eax, rect.top

mov ebx, rect.right
sub ebx, rect.left

invoke SetRect,ADDR rc,0,0,ebx,eax

mov eax, rect.top
neg eax ; -rect->top

mov ebx, rect.left
neg ebx

invoke SetWindowOrgEx,hdc,ebx,eax,ADDR pt
invoke PlayEnhMetaFile,hdc,hemf,ADDR rc
invoke SetWindowOrgEx,hdc,pt.x,pt.y,0

Posted on 2001-11-25 02:42:50 by forge