News:

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

MASM: Why must you be so difficult?

Started by 2-Bit Chip, September 03, 2009, 12:48:55 AM

Previous topic - Next topic

2-Bit Chip

How would this piece of code not work? What I am attempting to do is allocate 8 bytes for two DWORDS (the POINT structure) and place values into the structure.

The return value is the address for the new POINT structure.

POINT STRUCT
    X DWORD ?
    Y DWORD ?
POINT ENDS


...


NewPoint proc X:DWORD, Y:DWORD
    mov eax, alloc(SIZEOF POINT)
    mov [eax], DWORD PTR X
    mov [eax + 4], DWORD PTR Y
    ret
NewPoint endp






Would the below work? Wouldn't the local variable be destroyed right after the procedure ends?

NewPoint proc X:DWORD, Y:DWORD
    LOCAL lPoint: POINT
    mov [lPoint], DWORD PTR X
    mov [lPoint + 4], DWORD PTR Y
    ret
NewPoint endp

hutch--

Looks like you are trying to MOV memory to memory and there is no opcode to do that. Move it to a register first then to the memory operand you need it in.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

2-Bit Chip

HOLY MOLY! I forgot ALL about that! Thank you very, very, very much Hutch!!  :cheekygreen:

You DA MAN!

dedndave

it could be the use (or misuse) of the alloc macro
it returns a value, already in eax

        mov     hMem,alloc(nBytes)

moves the address (or handle, if you prefer) into hMem, but it moves it from eax
you might try this...

        alloc(nBytes)
        mov dword ptr [eax],X
        mov dword ptr [eax+4],Y
        ret

2-Bit Chip

Dave,

error A2070: invalid instruction operands
error A2070: invalid instruction operands


alloc(nBytes)

That single line would not work since the macro returns.

dedndave

ok - then store it into memory, then grab it back out - lol
i wonder if this would work...

        push    alloc(nBytes)
        pop     eax

it is kind of similar to str$() or something - it passes the result back in eax

MichaelW

2-bit,

Did you get what the first problem is? Stated another way, the problem is that [eax] and [eax+4] are memory operands (obviously), and (less obviously) X and Y are memory operands (effectively [ebp+8] and [ebp+0Ch]).
eschew obfuscation

dedndave

oh ! - lol - i didn't notice they were locals
that is why i use "[ebp+nnnn]" - i know what i am working with
the alloc may work as i suggested, then - nope
the push works

dedndave


NewPoint proc X:DWORD, Y:DWORD
        push    alloc(SIZEOF POINT)
        pop     eax
        push    X
        pop     [eax]
        push    Y
        pop     [eax+4]
        ret
NewPoint endp

2-Bit Chip

Thank you Michael and Dave.

Michael,

I thought of the [eax] and [eax+4] as register operands. That is probably why I messed up. :(

dedndave

i was thinking - this may be a better application for a macro, rather than a proc
you are introducing a lot of unnesseccary overhead with the proc

NewPoint MACRO X:Req,Y:Req
        push    alloc(SIZEOF POINT)
        pop     eax
        mov     [eax],X
        mov     [eax+4],Y
        ENDM

so long as X and Y aren't memory arguments

Ghandi

Dedndave, 'alloc' is a macro in itself which returns the result in EAX, so you could eliminate the PUSH and POP in your macro:


NewPoint MACRO X:Req,Y:Req
        alloc(SIZEOF POINT)
        mov     [eax],X
        mov     [eax+4],Y
        ENDM


HR,
Ghandi

dedndave

i tried that, Ghandi
the alloc macro is similar to the str$() (and a few others)
it only works if it is used in a context where it could be replaced with "eax"
if you try to assemble:
        alloc(nBytes)
the assembler sees:
        eax
and spits out an error
on the other hand, if you use push:
        push    alloc(nBytes)
the assembler sees:
        push    eax
and everything is ok

hutch--

The alloc, free macros are incredibly simple.


      alloc MACRO bytecount
        invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,bytecount
        EXITM <eax>
      ENDM

      free MACRO hmemory
        invoke GlobalFree,hmemory
      ENDM


It is purely a MASM notation issue that you MUST assign the return value to something, usually a memory operand that is used as a 32 bit pointer to the address of the allocated memory.


mov pMem, alloc(bytecount)

is seen as,
invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,bytecount
mov "your_target", eax


If you just wanted the return value in EAX you would not use the EXITM directive in the macro.

Thjis is the CHM help file content.

alloc

mov hMem, alloc(byte_count)

Description
Allocate a block of fixed memory.

Parameters
1. byte_count The number of bytes of fixed memory to allocate.

Return Value
The starting address of the block of memory.

Comments
Memory allocate with the alloc macro should be freed with the free macro.

Example
mov hMem, alloc(16384)
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave

also - allocating memory in 8 byte chunks is kind of inefficient
it depends on the application, of course, but i might look for a better alternative altogether
you are storing 2 dwords in allocated memory - now, you have to store that dword address
lose-lose situation
you'd be better off to save the 2 dwords
all the code it takes to do it the other way is more than 2 bytes