News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How does assume works?

Started by n00b!, October 31, 2008, 04:43:02 PM

Previous topic - Next topic

n00b!

Hello,
I read in the help files of MASM but since my English isn't that well, I did not understand it...

When I have something like this:
lea esi,rect
assume esi:ptr RECT

Then it's clear that in the first instruction esi gets the address of the label 'rect' (local rect:RECT).
But what does the second instruction?
"assume esi:ptr RECT"
RECT is a structure, but I don't get what the whole instruction does...

At the end follows a "assume esi:nothing"...

Could somebody please explain it in a way that a noob would understand (maybe not in some high and written-English ^^')
That would be great, Thanks!

Mirno

When you use the assume directive, you tell MASM that you want to treat that register as a pointer to some structure type (like rect).

Because a structure is not a single simple data type, you'd need to jump through some hoops to look at the specific elements.
You can then use esi as if it were that structure type


mov esi.element1, 1234
mov esi.element2, 5678


Then you use assume <reg>:nothing to set it back to "normal" use.

Mirno

n00b!

But isn't a register maximal 4 Bytes big in size?
So what about:?

foo struct
a dd ?
b dd ?
foo ends

mov esi.a, 5
mov esi.b, 9

Mirno

Assume is telling MASM to treat the register like a pointer, rather than a normal register...
So "mov esi.a, 5" is in fact "mov [esi + 0], 5"
And "mov esi.b, 9" is "mov [esi + 4], 9".

That's all done behind the scenes, and the "+ 0" and "+ 4" are all calculated based on the structure. It makes code easier to understand, and self maintaining (if you add something inbetween a and b in your struct, masm will update the "+4" to "+8" or whatever is needed).

The problem with assume is that if you forget, you can go wrong - MASM treats the register like a pointer, you're thinking it's treating it like a register... It can be confusing.

You can also use:

mov (foo ptr [esi]).a, 5
mov (foo ptr [esi]).b, 9

Without the assume, and it's a bit more obvious what you're doing (I prefer this method, although it's more typing it is clearer to the reader of the code).

Mirno

n00b!

Ähh...

Couldn't I just type:?
local a:RECT
mov [a.right], 10


And this would do the same:?
local a:RECT
lea edi, [a]
assume edi:ptr RECT
mov [edi].right, 10


Or am I a total dummy and didn't even get a bit of it?
If it's not like that, what would be the advantage of using assume?

jj2007

Another option that works without assume:

include \masm32\include\masm32rt.inc

.code
AppName db "Masm32:", 0
rc RECT <1,2,3,4>


start: mov esi, offset rc
print "top:", 9
mov eax, [esi.RECT.top]
print str$(eax), 13, 10
print "bottom:", 9
mov eax, [esi.RECT.bottom]
print str$(eax), 13, 10
getkey
exit

end start


EDIT: Our posts crossed. a and b work equally well, but a is 3 bytes, b is 5 bytes long. For long structures, it may matter.

a:   mov eax, [esi.RECT.top]
b:   mov eax, rc.top

8B46 04                     mov eax, dword ptr [esi+4]
A1 0C104000                 mov eax, dword ptr [NewWin32.40100C]

n00b!

Oh, sure...
That's the point! Thanks  :P

I thought of it but somehow, I can't remember what I continued to think, I discarded that notion...