Hi guys. I'm a beginner on ASM, and have a lot of questions in mind!

One of them is related to Invoke and CALL (I'm using MASM to code).

I'll show an example (I don't know if theses examples are right. Correct me if you see it's wrong, I'm a newbie):

Let's say I want to call the DispatchMessage function in Assembler.

In C++, all that we could do is this:

DispatchMessage(&msg);

In Assembler, using the Invoke command, we could do:

Invoke DispatchMessage, ADDR msg

But how Do I do this using the Instruction CALL?

I know that we have to push all the parameters to the STACK (in inverse order) before we call the function, but I don't know a similar for ADDR.

For example:

push msg
CALL DispatchMessage


It won't work because we have to pass 'msg' as an Adress (Segment:Offset).
I tryied to use this:


push OFFSET msg
CALL DispatchMessage


But it didn't work to, because OFFSET only returns the Offset part of the adress.
So, how do I get the Segment:Offset of an Adress, so I can push the correct value and call the DispatchMessage function?

Thank you a lot
Fernando
Posted on 2003-04-24 15:24:59 by FERNANDO-BRASIL
lea eax,msg (or mov eax,offset msg
push eax
call ....

Raymond
Posted on 2003-04-24 15:29:31 by Raymond
Why I can't do

push OFFET msg

directly, and have to do this:

mov register, OFFSET msg
push register


?

Sorry for the stuped question...
Fernando
Posted on 2003-04-24 15:38:37 by FERNANDO-BRASIL

...
It won't work because we have to pass 'msg' as an Adress (Segment:Offset).
...

No, you only pass the offset in win32asm, thus the address is simply the offset, using
push offset msg

call DispatchMessage

is how we can do it, take a look in for instance \masm32\example3\tstyle\tstyle1\tstyle1.asm (line 145, btw \masm32\example3\tstyle\tstyle2\tstyle2.asm contians the same code on line 175) there you can see the above lines, in a working example.

You can do but IIRC it's slower than . If msg is a local then you must use the lea instruction to calculate it's address.

There are no stupid questions, we were all there once, some longer than others, nothing to be ashamed of. :)
Posted on 2003-04-24 15:43:32 by scientica
You'll have to ask Microsoft why they did not include that as part of their syntax.

Raymond
Posted on 2003-04-24 15:44:38 by Raymond
mov reg, offset / push reg == superfluous. You waste time and gains are not noticable.

However, there's a reason for the "lea reg, offset / push reg" done by masm on invoke: you can't push the offset of a stack variable, as it's relative to ESP, and offset thus isn't known as build time.

Furtheremore, invoke is preferred to push+call, as it handles error checking (number of parameters, type of parameters (doesn't mean much with hutch masm32 "everything is a dword")), does some size conversion (that is buggy, though), and handles possible cleanup (C calling convention).
Posted on 2003-04-24 15:47:30 by f0dder
The offset directive only works when the address is known at compile time. If msg is a local, or an argument to a function, its address is not known, it is dependant on the ebp register. The actual code it will generate will be ebp +/- somevalue.

The push instruction can only push a constant, a register, or the contents of a memory location pointed to by a constant or register. It cannot push a register with a modifier (+ some value).
So instead you must calculate the address of the variable on the stack, this is done with lea. This will assemble to something like:
lea eax, [ebp + somenumber]

This is actually what addr will do also if the variable is local (if it is defined at compile time, it will push the offset).

If you use the /Fl<filename> switch with masm, you can look at the actual code that masm generates, for things like invoke, addr etc.

Mirno
Posted on 2003-04-24 15:54:45 by Mirno
Thank you guys!

Now I understood why we have to use LEA to local variables, and now my code is running well without INVOKE (I'm using CALL to call every function now).

But I have a question yet.

I was reading a e-book here, and there they say I have to pop all values I pushed on the STACK before the CALL instruction.

But, instead of Poping the values, Can I 'sub' the values from ESI?

For example:

lea eax, msg
push eax
CALL DispatchMessage
sub ESI, 4


Thank you again.
Fernando
Posted on 2003-04-24 16:04:07 by FERNANDO-BRASIL
you don't pop, and you don't sub, and you don't use esi.
You add, and you work with esp. Furthermore, this is only done for C proto functions, not STDCALL (which 99% of windows API is).

And again, do yourself a favor and do invoke.
Posted on 2003-04-24 16:06:06 by f0dder
Ok f0dder!

I'm coding with CALL only as a test. It's my 3th day learning ASM, so I want to test everything I can!! :)

But later, I will use invoke in my code!

I'm trying not to use instructions like INVOKE, .IF, .WHILE, LOCAL, etc yet because I want to learn the real Assembler! This was my reason to be here trying to code with Asm.

By the way, before we close this thread, I would like to ask something...

Why do we use brackets? [ ]

I have an e-book here but I couldn't understand their words...

They say it's related to address... But It's strange for me... It gets more strange when there's sum or multiplication there, like:

Posted on 2003-04-24 16:34:45 by FERNANDO-BRASIL


I'm coding with CALL only as a test. It's my 3th day learning ASM, so I want to test everything I can!! :)

But later, I will use invoke in my code!

That's a very good attitude - understand how stuff works, and make life easier for yourself afterwards.

Stuff like IF/WHILE... ho humm. I don't really like it, I'd rather code in a HLL if I need stuff like that. Matter of taste.
LOCAL is quite fine though, saves you the hassle of memorizing ESP offsets.

Brackets... well, the indicate "memory reference".

mov eax, esi ; EAX = ESI
mov eax, ; EAX = what ESI points to

with masm, "mov eax, variable" and "mov eax, " is the same - the most "correct" for is the one with the brackets, as you show you're doing a memory reference. You're getting the value of variable - dereferencing the offset of the variable. A lot of people have been confused because masm doesn't require , and think they can do double dereferencing - which x86 doesn't support.

Stuff like "" might be a bit confusing at first, especially which encodings are supported, but it's nice once you get the hang of it.
Posted on 2003-04-24 16:42:45 by f0dder
why we use brackets :

First you have to understand a little about addressing. When you have a pointer to an address the number it contains is a memory address. Usually you want the data that it points to, the address is not normally important for you to know. When you get the data at a referenced address (one that is pointed to) that is called dereferencing. The way you tell MASM that the number you are giving it is actually an address pointing to the data and not the data itself is by using brackets. Example :

addr data

0001 100
0002 123
0003 432
0004 993

if edi = 1 then this will be the result :

mov eax,edi
; eax will equal 1

mov eax,
; eax will equal the value at address 1 (in this case 100)

The file \MASM32\HELP\ASMINTRO.HLP that came with MASM32 will explain alot of the basic concepts to you, you should read it as it will help you alot.

EDIT: Darn that f0dder is fast :)
Posted on 2003-04-24 16:44:52 by donkey
sometimes, donkey - but I'm off for bed soon :)
btw, note that masm will not always do what you expect with regards to brackets... doesn't matter when you're doing "normal" programming, though.

FERNANDO-BRASIL, don't be afraid to keep posting here, not even "silly stuff" - you seem to be putting in an effort and be able to comprehend stuff :alright:
Posted on 2003-04-24 16:47:32 by f0dder
This means that these two line have the same meaning?:

lea eax, msg
mov eax,
Posted on 2003-04-24 16:50:38 by FERNANDO-BRASIL
Ok, thank you f0dder!

:-) You're being so patient with me to!
Posted on 2003-04-24 16:53:03 by FERNANDO-BRASIL
nope. Lea gets the address of the message (should only be used for local esp/ebp relative variables, offset is more efficient for global memory), while the mov gets the content of the variable.
Posted on 2003-04-24 16:53:16 by f0dder
I thought he was making a 16-bit application? You guys are just confusing him :P



This is how you do it:
push ds
push msg
call far DISPATCHMESSAGE

Or, if msg is on the stack:
push ss
lea ax,msg
push ax
call far DISPATCHMESSAGE

Just as the Win32 ones do, the Win16 APIs will adjust the stack automatically when returning, with a retf n. But unlike Win32, parameters to functions are put in reverse order.
Like this:
push 0
push ds
push offset TheText
push ds
push offset TheCaption
push 0
call MESSAGEBOXA

But you should probably move on to Win32, that's what all the popular kids do.
Posted on 2003-04-24 16:54:35 by Sephiroth3
I think I understood the brackets...

We use brackets not to get the Address of a variable or a register, but to say that the value inside this variable or register is an address...

Is this correct?
Posted on 2003-04-24 17:05:12 by FERNANDO-BRASIL
humm, not entirely sure I deciphered that correctly, so here's an example :)

mov eax, 0400000h ; an semi-arbitrary value - a valid address under win32
mov ebx, eax ; ebx = 0400000h
mov ebx, ; ebx = "whatever is at memory location 0400000h"

Oh, and forget about 16bit coding, start with 32bit as it's easier. Only go 16bit if you have to.
Posted on 2003-04-24 17:09:30 by f0dder
Ok. I think now the brackets are clear for me.

Let's say I have two DWORD created sequentially in the STACK. The first DWORD is called var1 and the second, var2.

var1 = 00FFh;
var2 = FF00h;

If I do this code:

lea eax, var1
mov edx, ; -4, since the STACK grows down


Will result in EDX having FF00h as its value?

What I imagined here, is that var1 for example, would be in position 100 in memory, and var2 in 96. So, executing LEA on var1, would move to EAX the value 100. Then, if we move the contents of memory position eax-4 (100-4), we will be moving the contents of var2.

Is this wrong?
Posted on 2003-04-24 17:20:48 by FERNANDO-BRASIL