Hi,
I'm new to assembler and have a couple of question on some simple code. First the code:

;Purpose: Swap Parameter1 & Parameter2 values passed by reference to this routine
;vb code -> res& = CallWindowProc(VarPtr(InCode(1)), VarPtr(lng1&),VarPtr(Lng2&), 3&, 4&)
;where Long1 is pointer to parameter1 and Long2 is pointer to paremeger2
.586
.model small
.code

long1 equ
long2 equ
long3 equ
long4 equ

;Save Registers into Stack
push ebp
mov ebp,esp
push ebx
;push ecx

;Save contents of long1 to ecx
mov ebx,long1 ;ebx contains pointer to long1
mov ecx, ;ecx now contains contents of long1
;mov ecx, ;Why doesn't this work?

;Save contents of long2 to eax
mov ebx,long2
mov eax, ;eax now contains contents of long2

;put contents of long2 into long1
mov ebx,long2 ;move the contents of long2(eax) into ptr to long2
mov ,ecx ;put eax into long1

;put contents of long1 into long2
mov ebx,long1
mov ,eax

;Restore Registers from Stack
pop ebx
mov esp,ebp
pop ebp
;pop ecx

;Finish
ret 16
END


Question 1 - when I try to push and pop the ecx register, my program gpf's - Is there a reason i shouldn't be doing this?

Question 2 - when I try to move directly to ecx (mov ecx,), gpf again.

Anyone know why I shouldn't do this?


Thanks - Newbie Jack

:stupid:
Posted on 2002-02-25 23:06:12 by JackRazz
first, you should pop ecx before popping ebx. Remember you're dealing
with a LIFO stack :).

Second, "mov reg, var" and "mov reg, " mean exactly the same, masm
just lets you skip the square brackets when dealing with variables. This
has lead to a lot of confusion, with people thinking you can do indirection
through memory. But you can't, and thus have to load the pointer into a
register and do indirection through the register (like you're currently
doing).

I'd also recommend you to take advantage of masm's PROC syntax... you
can let the assembler deal with setting up / clearing the stack frame,
where the arguments are located relative to ebp, and doing the right
amount in the "ret x" statement. If you need an example, just let us know,
and I or somebody else can come up with something.
Posted on 2002-02-25 23:19:35 by f0dder
Jack,

When you are using the stack with either PUSH/POP, always make sure you pop what you push in the right order.

For example, when you have 3 registers that you wish to preserve, you push them in the order that suits you.


push eax
push ecx
push edx

To restore them to their original values, you POP them in reverse.


pop edx
pop ecx
pop eax

This is also required when you manually control the entry and exit of a procedure as you must preserve both ESP and EBP between procedure calls.

It is worth learning what you are doing at the moment but once you have learnt, you will probably use the standard PROC system in MASM as it is very reliable and it automates the stack handling.

Regards,

hutch@movsd.com
Posted on 2002-02-25 23:27:46 by hutch--
on the stack push/pop - worked great after I changed them. Thanks


"Second, "mov reg, var" and "mov reg, " mean exactly the -same, masm just lets you skip the square brackets when dealing with variables. This has lead to a lot of confusion, with people thinking you can do indirection through memory. But you can't, and thus have to load the pointer into a register and do indirection through the register (like you're currently
doing). "

Yep, thats what confused me. Is this a MASM thing or all assembly languages thing?


"I'd also recommend you to take advantage of masm's PROC syntax... you can let the assembler deal with setting up / clearing the stack frame, where the arguments are located relative to ebp, and doing the right amount in the "ret x" statement. If you need an example, just let us know, and I or somebody else can come up with something."

Been thinking about that - I'll give it a try. Something like:
MyFirstProc PROC uses eax ebx ecx Long1:dword, Long2:dword
...
endproc
I better get an example<grin>.


Thanks - Jack
Posted on 2002-02-25 23:55:20 by JackRazz

Yep, thats what confused me. Is this a MASM thing or all assembly languages thing?

Many assemblers (including masm) are pretty lax and allow you to skip the brackets.
Nasm requires the brackets for data access, and because of that you can skip the
"offset" (and just write the variable name) when you need the address of a variable.
This is a personal taste and almost a religious matter, most people seem to prefer
not writing brackets. I try to bash myself into remembering them, as I can skim
quickly through pages and pages of code and still have a general idea of what's
going on.

As for register preservation... you only really need to preserve ebx esi edi esp ebp
if you're writing standard code (and of course you only need to push/pop them if
you use them). Of course it can be a good idea to preserve other registers if your
own program logic depends on it ;), but the win32 standard only requires you to
preserve the ones I mentioned above.

As hutch said, it does pay off knowing what's going on behind the scenes. You
can use a disassembler or debugger, or even a ml.exe command line switch (I'll
leave it as an excercise for you to find the right one ;)) to see what basic
asm code is generated from the higher-level helping stuff in masm.
Posted on 2002-02-26 00:05:15 by f0dder