kolibrios-gitea/programs/jpegview/trunk/memlib.asm

211 lines
3.3 KiB
NASM
Raw Normal View History

movedata:
push eax
xor eax,eax
sub eax,edi
and eax,3
xchg ecx,eax
sub eax,ecx
jle .l1
rep movsb
mov ecx,eax
shr ecx,2
rep movsd
and eax,3
.l1: add ecx,eax
rep movsb
pop eax
ret
mallocz:
call malloc
pushad
add ecx,3
xor eax,eax
shr ecx,2
rep stosd
popad
ret
mresize1: popad
xor edi,edi
stc
mresize2: ret
mresize: ; puntero en di ncr retorna nuevo puntero en di
test edi,edi
jz malloc
cmp ecx,[edi-4]
je mresize2
call free
malloc:
mov edi,ecx
jecxz mresize2
pushad
mov esi,iniciomemoria+4
lea ebx,[ecx+3]
and ebx,-4 ;redondeo a 4
.l1: mov edi,esi
add esi,[esi]
jc mresize1
lodsd
cmp eax,ebx
jc .l1
cmp esi,[iniciomemoria+8]
jc .l2
jne mresize1
lea edx,[ebx+esi+4]
cmp edx,[iniciomemoria+12]
jnc mresize1
mov [iniciomemoria+8],edx
.l2: pop dword [esi-4]
push esi
sub eax,ebx
je .l3
sub eax,4
mov [esi+ebx],eax
jz .l3
;fragmentar
add ebx,4
add [edi],ebx
mov eax,[esi]
sub eax,ebx
mov [esi+ebx],eax
popad
ret
.l3: lodsd
add eax,4
add [edi],eax
popad
ret
realloc: test edi,edi
jz malloc
jecxz free
pushad
pop esi
mov eax,[edi-4]
call malloc
push edi
cmp ecx,eax
jc .l1
mov ecx,eax
.l1: push esi
call movedata
pop edi
call free
popad
.l2: ret
free: ;puntero en di
;no se comprueban los punteros
;retorna di=0 , ncr
test edi,edi
jz realloc.l2
pushad
pop edi
mov ebp,[edi-4]
dec ebp
and ebp,-4 ;redondeo a 4,dx=dx-4
xor edx,edx
push edx
mov edx,iniciomemoria+4
mov esi,edx
;buscar puntero libre anterior
.l1: mov ebx,esi
lodsd
add esi,eax
cmp esi,edi
jc .l1
;enlazar
mov ecx,esi
sub ecx,edi
sub eax,ecx
sub ecx,4
mov [ebx],eax
;fusionar con el anterior
cmp eax,[ebx-4]
jne .l2
cmp ebx,edx
je .l2 ;no fusionar con el primero
mov edi,ebx
add eax,4
add ecx,eax
add ebp,eax
.l2: mov ebx,ebp ;fusionar con bloques de tama<6D>o 0
.l3: add ebx,4
test dword [edi+ebx],-1
jz .l3
cmp ebx,ecx
jne .l4
;fusionar con el siguiente
add ebx,[esi-4]
add ecx,[esi]
add ebx,4
add ecx,4
cmp esi,[edx+4]
jne .l4
mov [edx+4],edi
.l4: mov [edi-4],ebx
mov [edi],ecx
popad
ret
add_mem: ;edi,ecx ;el ultimo bloque libre debe ser >8 bytes para poder fragmentarlo
cmp ecx,64
jc .l1
add ecx,edi
add edi,3
and edi,-4
and ecx,-4
mov eax,ecx
sub ecx,edi ;redondeo
xchg eax,[iniciomemoria+12]
cmp edi,eax
jna .l1
lea esi,[edi+4]
mov edx,esi
xchg esi,[iniciomemoria+8]
neg edx
mov [edi],edx
mov [edi+4],edx
lea edx,[edi-4]
sub edi,esi
mov [esi],edi
sub eax,4
sub eax,esi
mov [esi-4],eax
add esi,eax
sub edx,esi
mov [esi],edx
.l1: ret
check_mem: ;busqueda de errores en la memoria
;retorna edx nbloques o 0 si error,ecx memoria libre
;ncr: ebp,ebx,eax
mov edi,iniciomemoria
mov esi,edi
xor edx,edx
mov ecx,[edi]
neg ecx ;el primer bloque no cuenta
.l1: add ecx,[edi]
add edi,4
add edi,[edi]
.l2: inc edx
add esi,[esi]
jc .l4
add esi,7
jc .l3
and esi,-4
cmp esi,edi
jc .l2
je .l1
jmp .l4
.l3: test edi,edi
jnz .l4
add ecx,[iniciomemoria+12]
ret
.l4: xor edx,edx
stc
ret