user3854783
user3854783

Reputation:

malloc and free x86 NASM + compiling

I have been teaching myself x86 assembly and have been looking at doing basic malloc() and free() calls. I have spent quite a bit of time searching but most examples are for 64-bit or only show the malloc call without the free, etc. I even wrote this in c, then compiled and disassembled it, which helped but gcc adds a lot of other instructions.

Here is a basic example I made of what I was able to figure out, please let me know if this is correct or if there is anything else I should be doing:

global _start
; glibc stuff
extern _malloc, _free

section .data
  err: db "malloc failed!", 10, 0
    .len: equ $ - err

section .bss
  mptr resd 1   ;pointer to begining of malloc'd memory

section .text
_start:

  push 20       ;allocate 20 bytes
  call _malloc  ;call malloc
  add esp, 4    ;clean pushed imm

  test eax, eax ;check for malloc error
  jz merror

  mov [mptr], eax ;store address

  mov byte [eax], 0
  mov byte [eax + 1], 1

  push mptr     ;push address
  call _free    ;call free
  add esp, 4    ;clean push

exit:
  mov eax, 0x1
  int 80h

merror:
  mov eax, 0x4
  mov ebx, 0x1
  mov ecx, err
  mov edx, err.len
  int 80h
  jmp exit

The second part to my question is compiling it. From what I was able to find I need to link /lib/ld-linux.so.2. So in my makefile I have the following but it errors out:

mem: mem.asm
    nasm -f elf mem.asm
    ld -melf_i386 -lc -I /lib/ld-linux.so.2 mem.o -o mem

This is the error I get when trying to compile:

enter image description here

As I said I am a noob at x86 so if you also have any comments for better ways to do things I would appreciate those too! :)

UPDATE :

So I went ahead and used gcc and got that to work (without and errors at least):

mem: mem.asm
    nasm -f elf mem.asm
    gcc -m32 mem.o -o mem

However when I went to run it it crashed big time: enter image description here

I am clearly doing something wrong with free but as I mentioned, I wasn't positive about my use of malloc and free since I couldn't find any solid examples. Any clues?

Upvotes: 1

Views: 3298

Answers (1)

user3854783
user3854783

Reputation:

Thanks to everyone for the help! So first I was able to get the linking errors fixed by using gcc to link instead of ld:

mem: mem.asm
    nasm -f elf mem.asm
    gcc -m32 mem.o -o mem

In order to get that to work I needed to change the names of the functions from _malloc and _free to malloc and free. I also had to change the standard global _start to global main in order to get gcc happy. This let it compile and link without errors but as you saw in the update the program crashed horribly when it came time to free the memory.

This was because I was pushing the wrong address to the stack. I initially had the instruction push mptr but that was pushing the address of mptr to the stack rather than the address it was pointing to, hence the error. A simple update to the instruction in order to push the correct address to the stack allowed my simple program to run without errors:

push dword [mptr]

The final result:

global main
; glibc stuff
extern malloc, free

section .data
  err: db "malloc failed!", 10, 0
    .len: equ $ - err

section .bss
  mptr resd 1   ;pointer to begining of malloc'd memory

section .text
main:

  push 20       ;allocate 20 bytes
  call malloc   ;call malloc
  add esp, 4    ;clean pushed imm

  test eax, eax ;check for malloc error
  jz merror

  mov [mptr], eax ;store address

  mov byte [eax], 0     ;store 0 at index 0
  mov byte [eax + 1], 1 ;store 1 at index 1

  push dword [mptr]     ;push address
  call free             ;call free
  add esp, 4            ;clean push

exit:
  mov eax, 0x1
  int 80h

merror:
  mov eax, 0x4
  mov ebx, 0x1
  mov ecx, err
  mov edx, err.len
  int 80h
  jmp exit

Thanks again to everyone for the help and thanks Peter Cordes for giving me a chance to provide a proper answer! :)

I'm sure i'll be back with more noob x86 questions as my journey continues!

Upvotes: 3

Related Questions