I’m trying to make simple alloc and free functions from the ProgrammingGroundUp book but my code isn’t working and I’m kinda stuck.
I am using that commands when i compile the program.
as --32 myalloc.s -o myalloc.o
gcc -m32 -no-pie main.c myalloc.o -o prog
.data
heap_begin:
.long 0
heap_end:
.long 0
.equ UNAVAIL, 0
.equ AVAIL, 1
.equ SYS_BRK, 45
.equ SYS_CALL, 0x80
.equ HDR_SIZE, 8
.equ HDR_AVAIL_OFFSET, 0
.equ HDR_SIZE_OFFSET, 4
.text
.globl alloc_init
.type alloc_init, @function
alloc_init:
pushl %ebp
movl %esp, %ebp
movl $SYS_BRK, %eax
movl $0, %ebx
int $SYS_CALL
incl %eax
movl %eax, heap_begin
movl %eax, heap_end
movl %ebp, %esp
popl %ebp
ret
.globl alloc
.type alloc, @function
#eax for heap_begin
#ebx for heap_end
#ecx for SIZE
#edx for Chunck size
alloc:
pushl %ebp
movl %esp, %ebp
movl heap_begin, %eax
movl heap_end, %ebx
alloc_lp:
cmpl %eax, %ebx
je break
movl 8(%ebp), %ecx
movl HDR_SIZE_OFFSET(%eax), %edx
cmpl $UNAVAIL, HDR_AVAIL_OFFSET(%eax)
je next_chunk
cmpl %edx, %ecx
jle allocate_here
JMP next_chunk
next_chunk:
addl $HDR_SIZE, %eax
addl %edx, %eax
JMP alloc_lp
allocate_here:
movl $UNAVAIL, HDR_AVAIL_OFFSET(%eax)
addl $HDR_SIZE, %eax
movl %ebp, %esp
popl %ebp
ret
break:
addl $HDR_SIZE, %ebx
addl %ecx, %ebx
pushl %eax
pushl %ebx
pushl %ecx
movl $SYS_BRK, %eax
int $SYS_CALL
cmpl $0, %eax
je error
popl %ecx
popl %ebx
popl %eax
movl $UNAVAIL, HDR_AVAIL_OFFSET(%eax)
movl %ecx, HDR_SIZE_OFFSET(%eax)
addl $HDR_SIZE, %eax
movl %ebx, heap_end
movl %ebp, %esp
popl %ebp
ret
error:
movl $0, %eax
movl %ebp, %esp
popl %ebp
ret
.globl dalloc
.type dalloc, @function
dalloc:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
subl $HDR_SIZE, %eax
movl $AVAIL, HDR_AVAIL_OFFSET(%eax)
movl %ebp, %esp
popl %ebp
ret
Also i used chatgpt for test program in c
#include <stdio.h>
#include <string.h>
// Assembly fonksiyonlarını bildiriyoruz
extern void alloc_init();
extern void* alloc(int size);
extern void dalloc(void* ptr);
int main() {
printf("[C TEST] Heap allocator test starting...\n");
// Heap başlat
alloc_init();
printf("Heap initialized!\n");
// 1. blok al
char* block1 = (char*) alloc(16);
if (!block1) {
printf("alloc(16) failed!\n");
return 1;
}
strcpy(block1, "Hello Heap!");
printf("Block1: %s (addr=%p)\n", block1, block1);
// 2. blok al
char* block2 = (char*) alloc(32);
if (!block2) {
printf("alloc(32) failed!\n");
return 1;
}
strcpy(block2, "Another block here.");
printf("Block2: %s (addr=%p)\n", block2, block2);
// İlk bloğu geri bırak
dalloc(block1);
printf("Block1 freed.\n");
// 3. blok al (eski freed bölgeyi kullanabilir)
char* block3 = (char*) alloc(8);
if (!block3) {
printf("alloc(8) failed!\n");
return 1;
}
strcpy(block3, "Test");
printf("Block3: %s (addr=%p)\n", block3, block3);
return 0;
}
I tried to work out with two different remote computer but again it didn't work.
Also that's what i get when i use gdb Firstly;
Program received signal SIGSEGV, Segmentation fault. 0x5655620f in break ()
Also this is disassemble of the main
Dump of assembler code for function break:
0x565561f3 <+0>: add $0x8,%ebx
0x565561f6 <+3>: add %ecx,%ebx
0x565561f8 <+5>: mov $0x2d,%eax
0x565561fd <+10>: int $0x80
0x565561ff <+12>: cmp $0x0,%eax
0x56556202 <+15>: je 0x56556221 <error>
0x56556204 <+17>: mov %ebx,0x5655900c
0x5655620a <+23>: sub %ecx,%ebx
0x5655620c <+25>: sub $0x8,%ebx
=> 0x5655620f <+28>: movl $0x0,(%ebx)
0x56556215 <+34>: mov %ecx,0x4(%ebx)
0x56556218 <+37>: add $0x8,%ebx
0x5655621b <+40>: mov %ebx,%eax
0x5655621d <+42>: mov %ebp,%esp
0x5655621f <+44>: pop %ebp
%ebxin all other assembly functions too. You can find this when you search for i386 calling convention which registers must be saved/restored.