News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

How do I use the C function "free" to deallocate memory in masm?

Started by assembler, February 13, 2017, 01:26:12 AM

Previous topic - Next topic

assembler

When I tried to invoke the C function "free" (from msvcrt.lib) to deallocate some memory (allocated by previously invoking the C function "malloc") for the first time in masm, my masm application crashed on this point when my masm application invokes the free C function. Whenever I invoke any procedure in masm, I always pass at least 1 parameter/argument, i.e. I push at least one parameter/argument on stack on one line. The line that invokes the malloc C function succeeds, but the line that invokes the free C function fails. Later I changed the line that invokes the "free" C function to call the "free" C function, i.e. same as invoke, but no parameters passed and pushed onto stack and then application didn't crash. It seems that the C function "free" in masm deallocates the memory pointed by register "eax". It doesn't accept any parameter, i.e. I don't need to push the address of the memory that I desire to deallocate on stack before calling free, so never invoke it. In the same manner "malloc" could use the unsigned value of register eax to know how many bytes it should allocates before it modifies register eax, so it's unsigned value is now the address of the new allocated memory, or use any other register, like ebx, ecx or edx, to know how many bytes to allocate, so malloc could be "parameterless" like free, and the usage of it could be to use the "call" instuction only and never invoke, but malloc doesn't working like that, but I must always push to stack the number of bytes that it needs to allocate and then it only modifies register eax to store the new address of the allocated memory in it, but the value of register eax before the modification and value of any other register is don't care for malloc, unlike free that the value of register eax for it is care. I want to verify and make sure that I understood correctly that the C function "free" works in this way, and that I do deallocate memory when using the C function "free" this way.

Adamanteus

 As you decribed some type of undefined behavor of functions, I'll advise first to ensure particular presence of stack space, when calling C-runtime functions, as in this topic.

hutch--

A number of things, I don't know how you are using MASM, is it the MASM32 SDK or are you using it in another way ?  Now with the C functions, are they C static libraries or from MSVCRT ? Tell us a bit more and we may be able to help you.

assembler

Quote from: hutch-- on February 13, 2017, 01:52:02 AM
A number of things, I don't know how you are using MASM, is it the MASM32 SDK or are you using it in another way ?  Now with the C functions, are they C static libraries or from MSVCRT ? Tell us a bit more and we may be able to help you.

If you will ask me questions then I will tell you more you need to know to help me, well I do:


includelib \masm32\lib\msvcrt.lib


When I try either:


invoke free, mBlock


or


push mBlock
call free


Application crashes.

But when I do:


mov eax, mBlock
call free


Application doesn't. I can infer that the free function in masm uses register eax only as reference to the block of memory to deallocate. Everything else, like other registers (ebx, ecx, edx and etc), stack local variables and parameters/arguments, data segment (global variables) are don't care for it. I just want to make sure if my inference is correct and free does work this way in masm, because in C when I code in Visual Studio, the free function works differently, i.e. it accepts one parameter/argument: void*, where this parameter is the pointer to the block of memory to deallocate. The free function when coding in C isn't "parameterless", unlike in masm.

Vortex

Hi assembler,

If you want to use the msvcrt function free, you need to type crt_free and not free. The reason is that free is a member of masm32.lib :

Checking \masm32\m32lib\free.asm :

; #########################################################################

    ; -------------------------------------------------------
    ; This procedure was written by Ernie Murphy    10/1/00
    ; -------------------------------------------------------

      .386
      .model flat, stdcall  ; 32 bit memory model
      option casemap :none  ; case sensitive
      PUBLIC Alloc_pIMalloc

      include     \masm32\include\ole32.inc
     
      includelib  \masm32\lib\ole32.lib

    .data

    externdef Alloc_pIMalloc:DWORD

    .code

; #########################################################################

Free proc public pv:DWORD

    ; -------------------------------------------------------------
    ; Free frees a block of memory previously allocated through a call to Alloc.
    ; The number of bytes freed equals the number of bytes that were allocated.
    ; After the call, the memory block pointed to by pv is invalid and can no
    ; longer be used.
    ;
    ; Note The pv parameter can be NULL. If so, this method has no effect.
    ;
    ;
    ; EXAMPLE:
    ; invoke Free, pMem         ; frees the memory pointer to by pMem
    ;
    ; Uses: eax, ecx, edx.
    ;
    ; -------------------------------------------------------------
   
    ; free the memory
    push pv
    push Alloc_pIMalloc
    mov ecx, Alloc_pIMalloc
    mov ecx, [ecx]
    ; call IMalloc::Free
    call DWORD PTR [ecx] + 20   ; and you thought COM was hard, huh?   ;-)
    xor eax, eax                ; OK, this is a (void) function, but let's be consistant
    ret

Free endp
; #########################################################################

end


The prefix crt_ is required to avoid some naming conflicts.

invoke crt_free,...

\masm32\include\msvcrt.inc :

    externdef _imp__free:PTR c_msvcrt
    crt_free equ <_imp__free>

assembler

Quote from: Vortex on February 13, 2017, 06:40:38 AM
Hi assembler,

If you want to use the msvcrt function free, you need to type crt_free and not free. The reason is that free is a member of masm32.lib :

Checking \masm32\m32lib\free.asm :

; #########################################################################

    ; -------------------------------------------------------
    ; This procedure was written by Ernie Murphy    10/1/00
    ; -------------------------------------------------------

      .386
      .model flat, stdcall  ; 32 bit memory model
      option casemap :none  ; case sensitive
      PUBLIC Alloc_pIMalloc

      include     \masm32\include\ole32.inc
     
      includelib  \masm32\lib\ole32.lib

    .data

    externdef Alloc_pIMalloc:DWORD

    .code

; #########################################################################

Free proc public pv:DWORD

    ; -------------------------------------------------------------
    ; Free frees a block of memory previously allocated through a call to Alloc.
    ; The number of bytes freed equals the number of bytes that were allocated.
    ; After the call, the memory block pointed to by pv is invalid and can no
    ; longer be used.
    ;
    ; Note The pv parameter can be NULL. If so, this method has no effect.
    ;
    ;
    ; EXAMPLE:
    ; invoke Free, pMem         ; frees the memory pointer to by pMem
    ;
    ; Uses: eax, ecx, edx.
    ;
    ; -------------------------------------------------------------
   
    ; free the memory
    push pv
    push Alloc_pIMalloc
    mov ecx, Alloc_pIMalloc
    mov ecx, [ecx]
    ; call IMalloc::Free
    call DWORD PTR [ecx] + 20   ; and you thought COM was hard, huh?   ;-)
    xor eax, eax                ; OK, this is a (void) function, but let's be consistant
    ret

Free endp
; #########################################################################

end


The prefix crt_ is required to avoid some naming conflicts.

invoke crt_free,...

\masm32\include\msvcrt.inc :

    externdef _imp__free:PTR c_msvcrt
    crt_free equ <_imp__free>


Thanks for the reply! I can use crt_free, but I also can use the free from masm32.lib if I want. If I do, then always:


call free


Whenever register eax points at the memory to deallocate, am I right?

jj2007

call free chokes with "Error A2243: Invalid symbol type in expression: free". Unless you are coding case-insensitive, which would be a very bad idea.

Besides, Free expects one parameter on the stack. If it crashes, it means the parameter is bad. Which would be easy to check if you posted your complete code.

hutch--

These are the two macros used together in MASM32.

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

      free MACRO hmemory
        invoke GlobalFree,hmemory
      ENDM


Memory allocation strategies cannot be intermixed, you can also use the HeapAlloc() family or the VirtualAlloc() family of functions but match up the allocate / deallocate function, don't mix them. If you particularly want to use the C runtime versions, you must use the matching alloc / dealloc functions but others will not safely work.

You use the macro alloc like a function.

mov pMem, alloc(bytecount)
........
free pMem


assembler

Quote from: hutch-- on February 13, 2017, 11:24:43 AM
These are the two macros used together in MASM32.

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

      free MACRO hmemory
        invoke GlobalFree,hmemory
      ENDM


Memory allocation strategies cannot be intermixed, you can also use the HeapAlloc() family or the VirtualAlloc() family of functions but match up the allocate / deallocate function, don't mix them. If you particularly want to use the C runtime versions, you must use the matching alloc / dealloc functions but others will not safely work.

You use the macro alloc like a function.

mov pMem, alloc(bytecount)
........
free pMem


I have just got:

Quoteerror A2006: undefined symbol: alloc

And I don't find any information about both alloc and free macros in masm in google/internet!

How do you know about these? Where did you find them?

Seems like you have just invented and thought about these two macros right now (-_-).

hutch--

The two macros are in the macro file for the MASM32 SDK. If you are using something else, feel free to write your own.

> Seems like you have just invented and thought about these two macros right now (-_-).

Be a smartarse in here and you will be shown the door real fast.

assembler

QuoteBe a smartarse in here and you will be shown the door real fast.

What does this mean exactly?

jj2007

Quote from: assembler on February 13, 2017, 11:00:52 PMWhat does this mean exactly?

It means that you should study \Masm32\help really carefully before asking any further questions. RTFM, in short 8)

nidud

deleted

assembler

Quote from: nidud on February 14, 2017, 12:03:27 AM
Here's a test case for malloc() and free() using msvcrt.dll

;
; Build: ml -c -coff test.asm
; link /subsystem:console /nodefaultlib test.obj \masm32\lib\msvcrt.lib
;
.386
.model flat, c

malloc proto :dword
free proto :ptr
printf proto :ptr byte, :vararg
exit proto :dword

.data
format db "Address: %p", 10, 0
        .code

main proc

push 100
call malloc
add esp,4

push eax ; free(eax)
push eax
push offset format
call printf
add esp,8

call free
add esp,4

invoke malloc,100
push eax
invoke printf,addr format,eax
pop eax
invoke free,eax
        invoke exit,0

main endp

end main


I don't understand this code, why are you doing here ever:


add esp, 4


and


add esp, 8


???

Vortex

Hi assembler,

nidud is balancing the stack after calling the CRT functions malloc and printf. invoke does it automatically as it's a macro designed to handle stdcall and C functions calls.