.code32 .section .data parada_atual: .long 0 inicio_heap: .long 0 total_Livre: .int 0 total_Ocupado: .int 0 segmentos_Ocupados: .int 0 segmentos_Livres: .int 0 #Constantes .equ DISPONIVEL, 1 .equ INDISPONIVEL, 0 .equ BRK_INT, 45 #Informações do cabeçalho #Tamanho do cabeçalho .equ TAM_HDR, 8 #Posição da variável que indica se a memória está disponível .equ HDR_DISPONIVEL, 0 #Posição da variável que indica o tamanho .equ HDR_TAMANHO, 4 #Strings para imprMapa str_Inicio : .string "Inicio heap: %p \n" str_Ocupado : .string "Segmento %d: %d bytes ocupados\n" str_Livre : .string "Segmento %d: %d bytes livres\n" str_Ocupados_xx : .string "Segmentos Ocupados: %d/%d bytes\n" str_Livres_xx : .string "Segmentos Livres: %d/%d bytes\n" str_Aviso : .string "Nada foi alocado!!\n" .section .text .globl iniciomeuAlocaMem .type iniciomeuAlocaMem,@function #Inicialização do malloc - Guarda o inicio da heap na primeira vez que o programa é executado iniciomeuAlocaMem: pushl %ebp movl %esp, %ebp movl $BRK_INT, %eax movl $0, %ebx int $0x80 incl %eax movl %eax, parada_atual movl %eax, inicio_heap movl %ebp, %esp popl %ebp ret ##### Começo do malloc ##### .globl meuAlocaMem .type meuAlocaMem,@function #%eax = começo do heap #%ebx = parada atual #%ecx = parâmetro do malloc #%edx = tamanho da região de memória atual meuAlocaMem: pushl %ebp movl %esp, %ebp #Se o incio do heap está em 0 quer dizer que o malloc ainda nao foi inicializado, então a função iniciomeuAlocaMem é chamada #Caso contrario a função continua a alocar memória cmpl $0, inicio_heap je inicio jmp continua inicio: call iniciomeuAlocaMem jmp continua continua: movl 8(%ebp), %ecx movl inicio_heap, %eax movl parada_atual, %ebx jmp meuAlocaMemLoop meuAlocaMemLoop: #Se %eax e %ebx sao iguais isso significa que é necessário alocar mais memória. #A seção "interrupção" disponibiliza mais memória. #Isso é executado apenas uma vez. cmpl %eax, %ebx je interrupcao #Guarda o tamanho da memoria movl HDR_TAMANHO(%eax), %edx #Se o espaço está indisponivel, vai para o próximo espaço disponível cmpl $INDISPONIVEL, HDR_DISPONIVEL(%eax) je proximo #Se o espaço está disponível, compara o tamanho do bloco atual com o tamanho que voce quer alocar. cmpl %edx, %ecx jle aloca proximo: #%eax recebe o endereço da próxima região de memória addl $TAM_HDR, %eax addl %edx, %eax #Vai para a próxima posição de memória jmp meuAlocaMemLoop aloca: movl $INDISPONIVEL, HDR_DISPONIVEL(%eax) addl $TAM_HDR, %eax movl %ebp, %esp popl %ebp ret interrupcao: addl $TAM_HDR, %ebx addl %ecx, %ebx #Empilha %eax, %ebx e %ecx para que seus valores não sejam perdidos após a syscall pushl %eax pushl %ebx pushl %ecx #%eax contém o número da syscall de BRK #%ebx contém a ultima posição válida de memória (tamanho do headre + parâmetro do malloc) movl $BRK_INT, %eax int $0x80 #Após fazer a syscall de BRK o ponto de parada é setado para a última posição válida de memória (que estava em %ebx) cmpl $0, %eax je error #Recupera o valor de %eax, %ebx e %ecx popl %ecx popl %ebx popl %eax #Atualiza as informações do cabeçalho movl $INDISPONIVEL, HDR_DISPONIVEL(%eax) movl %ecx, HDR_TAMANHO(%eax) addl $TAM_HDR, %eax movl %ebx, parada_atual movl %ebp, %esp popl %ebp ret error: movl $0, %eax movl %ebp, %esp popl %ebp ret ##### Fim do malloc ##### ##### Começo do free ##### .globl meuLiberaMem .type meuLiberaMem,@function meuLiberaMem: pushl %ebp movl %esp , %ebp #Passa o parâmetro do free (memória que voce quer liberar) para %eax movl 8(%ebp), %eax #Muda a variável HDR_DISPONIVEL do cabeçalho de insdisponivel para disponivel movl $DISPONIVEL , -8(%eax) movl %ebp , %esp popl %ebp ret ##### Fim do free ##### ##### Começo do imprime mapa ##### .globl imprMapa .type imprMapa,@function imprMapa: pushl %ebp movl %esp, %ebp movl inicio_heap, %eax movl parada_atual, %ebx cmpl %eax, %ebx #Se a posição atual for o começo do heap significa que ainda não foi alocada memória je naoAlocou pushl inicio_heap pushl $str_Inicio call printf addl $8, %esp #%eax vai ser um contador de segmentos movl $1, %eax movl inicio_heap, %ebx jmp analisaMapa analisaMapa: #Empilha o tamanho do bloco pushl HDR_TAMANHO(%ebx) #Empilha o contador de segmentos pushl %eax cmpl $INDISPONIVEL, HDR_DISPONIVEL(%ebx) #Vai para imprimeOcupado caso a memória esteja insdisponível e para imprimeLivre caso a memória esteja disponível je imprimeOcupado jmp imprimeLivre imprimeOcupado: movl total_Ocupado, %edx movl segmentos_Ocupados, %ecx addl HDR_TAMANHO(%ebx), %edx addl $1, %ecx movl %edx, total_Ocupado movl %ecx, segmentos_Ocupados pushl $str_Ocupado call printf #Desempilha os parâmetros addl $4, %esp jmp continua_mapa imprimeLivre: movl total_Livre, %edx movl segmentos_Livres, %ecx addl HDR_TAMANHO(%ebx), %edx addl $1, %ecx movl %edx, total_Livre movl %ecx, segmentos_Livres pushl $str_Livre call printf #Desempilha os parâmetros addl $4, %esp jmp continua_mapa continua_mapa: popl %eax popl HDR_TAMANHO(%ebx) movl %ebx, %ecx addl $TAM_HDR, %ecx addl HDR_TAMANHO(%ebx),%ecx movl %ecx, %ebx cmpl parada_atual, %ebx je terminaMapa addl $1, %eax jmp analisaMapa terminaMapa: pushl total_Ocupado pushl segmentos_Ocupados pushl $str_Ocupados_xx call printf #Desempilha os parâmetros addl $12, %esp pushl total_Livre pushl segmentos_Livres pushl $str_Livres_xx call printf #Desempilha os parâmetros addl $12, %esp movl $0, total_Livre movl $0, segmentos_Livres movl $0, total_Ocupado movl $0, segmentos_Ocupados movl %ebp, %esp popl %ebp ret naoAlocou: pushl $str_Aviso call printf movl %ebp, %esp popl %ebp ret