flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > [SOLVED] kolibri(menuet) port: error handling trashes retadr

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 27 Apr 2020, 03:11
sources https://yadi.sk/d/HTs1wxZvp6BmYw

in case of UI all works properly, in case of succesful compilation all OK too.

but in case when fasm should display error page fault happend in code (ASSEMBLE.INC)
Code:
show_display_buffer:
        mov     eax,[tagged_blocks]
        or      eax,eax
        jz      display_done
        mov     esi,[labels_list]
        cmp     esi,eax
        je      display_done
      display_messages:
        sub     esi,8
        mov     eax,[esi+4] ; PROGRAM CRASHED HERE
        mov     ecx,[esi]
        sub     esi,ecx
        cmp     eax,10h
        je      write_addressing_space
        test    eax,eax
        jnz     skip_block
        push    esi
        call    display_block
        pop     esi
      skip_block:
        cmp     esi,[tagged_blocks]
        jne     display_messages
      display_done:
        ret     


registers at crash
eax = $0c3e34d8 (points to undefined area)
ebx = 0
ecx = $27000 (points to undefined area)
edx = $27000 (points to undefined area)
esi = $0c3e3738 (points to undefined area)
ebp = 0
esp = $20FE8 (stack content: $00000ce9,$00000d4e,$0001a348,$00004F20,$0000083A,$000002FE,undefined
eip = $5bd8
eflags = $1212

in proper case instead of crash should be output (in test case was that error):
Code:
flat assembler version 1.73.23
example.asm [36]:
 mow eax, 10    ; function 10 : wait until event
error: illegal instruction
    

crash happend indefinitely from error type (absence of source or whatever) and always at display_messages.

Tomasz, I understand that thour code correct. and bug somewhere in interface I produced.
But, can thou help where I could make mistake? thanks.

_________________
I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.


Last edited by ProMiNick on 27 Apr 2020, 16:14; edited 1 time in total
Post 27 Apr 2020, 03:11
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 27 Apr 2020, 09:04
Is it possible that "display_block" interferes with something? What happens if you replace it with a placeholder (just RETN instruction)?

Also, does it crash the same way no matter the size and contents of source (as long as there is an error)?
Post 27 Apr 2020, 09:04
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 27 Apr 2020, 09:11
display itself work correct:
file with content
display 'hello world'
db 0
compiled succesfuly and hello world displayed
even display with up to 1kb string to display displayed OK.
something interfered to display only at error handling
Post 27 Apr 2020, 09:11
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 27 Apr 2020, 09:21
My question was concerning the "display_block" function as defined by the interface. Please try reducing it to just a RETN as see if that changes anything.
And the second question was whether an error on a single-line source also causes a crash.
Post 27 Apr 2020, 09:21
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 27 Apr 2020, 10:52
I shrinked display_block to RETN.
Error still same.
But I see program succeed to show
Code:
flat assembler version 1.73.23
example.asm [36]: [
error: illegal instruction    
before crash

in case of 1 line source I see
Code:
flat assembler version 1.73.23
example.asm [1]: [
error: illegal instruction    
before crash
Post 27 Apr 2020, 10:52
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 27 Apr 2020, 11:06
Since the entire error message is generated and shown, it seems that the program makes it to "jmp exit_program" at the end of "assembler_error" handling - and yet it still somehow lands inside the "show_display_buffer" code later? Please try debugging what happens at the "exit_program" point.
Post 27 Apr 2020, 11:06
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 27 Apr 2020, 13:44
Is that normal that after exit program illegal instruction caused again?
Code:
display_line_data:
...
$E56:   mov     esi,error_suffix  ;error_suffix=$1AAE0, content ($2e,0,':',$20,'[')
$E5B:   call    $c88 ; call display_string

display_string:
$C88:   pushad
$C89:   cmp     byte[esi],0
$C8C:   jz      $C9A
$C8E:   mov     dl,[esi]
$C90:   call    $C07 ;call display_character

display_character:
$C07:   pushad
$C08:   cmp     dword[$1AAC2],8 ; there 8
$C0F:   jnz     $C78
$C11:   cmp     dl,$D ;there $2e
$C14:   jz      $C2F
$C16:   cmp     dl,$A ;there $2e
$C19:   jnz     $C31
;$C1B:   and     dword[$1AACF],$FFFF
;$C25:   add     dword[$1AACF],$7000A
;$C2F:   popad
;$C30:   ret
$C31:   mov     eax,[textxy] ;textxy=$1AACF, content $A3005A
$C36:   cmp     ax,[bottom_right]    ;bottom_right=$634,content $00CC
$C3D:   ja      $C2F
$C3F:   shr     eax,$10
$C42:   cmp     ax, [bottom_right+2]   ;bottom_right+2=$636,content $105
$C49:   ja      $C2F
$C4B:   mov     [dc],dl  ;dc=$1AAD3
$C51:   mov     eax,4 ;SF_DRAW_TEXT=4
$C56:   mov     ebx,[textxy]
$C5C:   mov     ecx,[sc.work_text] ;sc.work_text=$1F444,content 0
$C62:   mov     edx,dc
$C67:   xor     esi,esi
$C69:   inc     esi
$C6A:   int     $40
$C6C:   add     [textxy],0x00060000
$C76:   popad
$C77:   ret

$C95:   add     esi,1
$C98:   jmp     $C89

$C89:   cmp     byte[esi],0
$C8C:   jz      $C9A

$C9A:   popad
$C9B:   ret

$E60:   jmp     $95C ;exit_program=$95C

exit_program:
$95C:   cmp     [_mode],NORMAL_MODE
$963:   jnz     $978
$965:   mov     eax,$44 ; SF_SYS_MISC
$96A:   mov     ebx,$D  ; SSF_MEM_FREE
$96F:   mov     ecx,[memblock] ; memblock=$1E2C8, content $27000
$975:   int     $40
$977:   ret

$4F14:  jae     $4F0F

$4F0F:  call    $50BB

$50BB:  mov     eax,[$1DE54] ; content $0C3C67B4
$50C0:  sub     eax, $100
$50C5:  cmp     edi,eax
$50C7:  ja      $E65
$50CD:  lodsb
$50CE:  cmp     al,l
$50D0:  jz      $543C
$50D6:  jb      $5479
$50DC:  cmp     al,3
$50DE:  jb      $517A
$50E4:  jz      $52C2
$50EA:  cmp     al,4
$50EC:  jz      $53D8
$50F2:  cmp     al,$F
$50F4:  jz      $5113
$50F6:  cmp     al,$13
$50F8:  jz      $5108
$50FA:  cmp     al,$10
$50FC:  jnz     $F04 ; jnz illegal_instruction

illegal_instruction:
$F04:   push    $1A33C ; content 'illegal instruction',0
$F09:   jmp     $1091 ; jmp error_with_source

error_with_source:
$1091:  cmp     dword[$1DDBC],0 ; content 0
$1098:  jz      $D3D ; jz assembler_error    
Post 27 Apr 2020, 13:44
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 27 Apr 2020, 13:46
Nothing should be happening after "jmp exit_program", fasm does not expect anything more to happen when it jumps there, it should simply terminate the process.

If it is the RET instruction that is expected to end the process after "exit_program", you may need to restore the original stack frame (see libc version for an example).
Post 27 Apr 2020, 13:46
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 27 Apr 2020, 14:00
so, I understand why error caused again, I expect that in stack ret address to message processing - but there are retaddr of error handling.
how to fix that?
I cant fix it in system.inc - without error handling stack restored correctly.
I cant fix it in error.inc - it shoudnt affect other fasm variant.
so I shoud provide 2 different program exits.
Or check at exit errorflag and process stack accordig to it.


Last edited by ProMiNick on 27 Apr 2020, 14:27; edited 1 time in total
Post 27 Apr 2020, 14:00
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 27 Apr 2020, 14:08
This is all up to the interface implementation, the fasm's core does not need to know anything about that. It jumps to "exit_program" when it is finished, but because this state may be achieved through a jump from deep withing call stack, the ESP is not the same as it was when assembler core was started. Therefore if you want to be able to use the RET instruction there, you need to restore your old ESP first.
Post 27 Apr 2020, 14:08
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 27 Apr 2020, 14:33
I should store stack value for restoring in global variable?
Or there any error_flag that I could check at exit_process and if error handling shift stack top always on fixed value I could restore it via add esp,that value
Post 27 Apr 2020, 14:33
View user's profile Send private message Send e-mail Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 27 Apr 2020, 16:11
Thanks for help Tomasz.
https://yadi.sk/d/HTs1wxZvp6BmYw - I update source for kolibri.
Post 27 Apr 2020, 16:11
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 27 Apr 2020, 16:39
BTW, do you plan to port fasmg too? It uses very similar interfaces (although more polished), but also requires a malloc/realloc implementation (if OS does not provide one). I currently only have an implementation for x64 version, but I could prepare a similar one for 32-bit OSes if needed (I did in fact consider making a simple 32-bit malloc for the purpose of DOS version, but it never really felt needed, since I use Win32 version with HX under DOS anyway).
Post 27 Apr 2020, 16:39
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 27 Apr 2020, 16:53
That would be nice too.
Post 27 Apr 2020, 16:53
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 29 Apr 2020, 12:41
All right, I have prepared the most basic implementation of malloc/realloc. It is really straightforward and almost minimalistic, yet it still seems to works decently with fasmg.

This code is going to be a part of the fasmg's source base, therefore fasmg's license applies:
Code:
; a very basic implementation of malloc/realloc
; for porting fasmg to systems that do not have such API natively

struct MemoryHeader
        size dd ?               ; total size of this block, the lowest bit set for blocks in use
        preceding_size dd ?     ; total size of the block that precedes this one in memory (zero if this is an initial block of address range)
ends

struct FreeMemory
        header MemoryHeader
        right dd ?              ; next free block in cyclic list
        left dd ?               ; previous free block in cyclic list
ends

VALLOC_MIN = 100000h

valloc:
; in: ecx = requested minimum size
; out: eax - allocated block, ecx = allocated size, zero if failed
; preserves: ebx, esi, edi
; note:
;  this function requests raw memory from the OS;
;  it may allocate much more memory than requested (even entire available memory),
;  the obtained memory is kept indefinitely in the pool for malloc
;  and should be released by OS automatically when the process ends;
;  if the OS does not do it automatically, additional list of the memory areas
;  may need to be maintained to release them before exit
        cmp     ecx,VALLOC_MIN
        jbe     valloc_size_minimum
        dec     ecx
        and     ecx,(-1) shl 12
        add     ecx,1 shl 12
        jmp     valloc_size_ready
    valloc_size_minimum:
        mov     ecx,VALLOC_MIN
    valloc_size_ready:
        push    ecx
        invoke  VirtualAlloc,0,ecx,MEM_COMMIT,PAGE_READWRITE
        pop     ecx
        test    eax,eax
        jz      valloc_failed
        retn
    valloc_failed:
        xor     ecx,ecx
        retn

malloc:
malloc_fixed:
malloc_growable:
; in: ecx = requested size
; out: eax - allocated block, ecx = allocated size, on error jumps to out_of_memory (does not return)
; preserves: ebx, esi, edi
        dec     ecx
        and     ecx,(-1) shl 2
        add     ecx,1 shl 2
        jc      out_of_memory
        add     ecx,sizeof.MemoryHeader
        jc      out_of_memory
        cmp     ecx,sizeof.FreeMemory
        jae     malloc_size_ok
        mov     ecx,sizeof.FreeMemory
    malloc_size_ok:
        mov     eax,[malloc_freelist]
        test    eax,eax
        jz      malloc_new
    find_fit:
        cmp     ecx,[eax+MemoryHeader.size]
        jbe     malloc_use_block
        mov     eax,[eax+FreeMemory.left]
        cmp     eax,[malloc_freelist]
        jne     find_fit
    malloc_new:
        push    ecx
        add     ecx,sizeof.MemoryHeader
        jc      out_of_memory
        call    valloc
        test    ecx,ecx
        jz      out_of_memory
        xor     edx,edx
        mov     [eax+MemoryHeader.preceding_size],edx
        pop     edx
        push    eax
        sub     ecx,edx
        cmp     ecx,sizeof.FreeMemory+sizeof.MemoryHeader
        jb      no_space_for_free_block
        mov     [eax+MemoryHeader.size],edx
        add     eax,edx
        mov     [eax+MemoryHeader.preceding_size],edx
        mov     edx,ecx
        sub     edx,sizeof.MemoryHeader
        dec     edx
        and     edx,(-1) shl 2
        add     edx,1 shl 2
        mov     [eax+MemoryHeader.size],edx
        mov     ecx,[malloc_freelist]
        jecxz   freelist_empty
        mov     [eax+FreeMemory.left],ecx
        mov     edx,eax
        xchg    edx,[ecx+FreeMemory.right]
        mov     [eax+FreeMemory.right],edx
        mov     [edx+FreeMemory.left],eax
        mov     edx,[eax+MemoryHeader.size]
        jmp     free_block_ready
    no_space_for_free_block:
        sub     ecx,sizeof.MemoryHeader
        add     edx,ecx
        mov     [eax+MemoryHeader.size],edx
        jmp     append_limiter
    freelist_empty:
        mov     [eax+FreeMemory.left],eax
        mov     [eax+FreeMemory.right],eax
    free_block_ready:
        mov     [malloc_freelist],eax
    append_limiter:
        add     eax,edx
        mov     [eax+MemoryHeader.preceding_size],edx
        mov     [eax+MemoryHeader.size],sizeof.MemoryHeader or 1        ; cannot be freed
        pop     eax
    finish_malloc:
        mov     ecx,[eax+MemoryHeader.size]
        or      [eax+MemoryHeader.size],1
        add     eax,sizeof.MemoryHeader
        sub     ecx,sizeof.MemoryHeader
        retn
    malloc_use_block:
        mov     edx,[eax+MemoryHeader.size]
        sub     edx,ecx
        cmp     edx,sizeof.FreeMemory
        jb      use_whole_block
        mov     [eax+MemoryHeader.size],ecx
        mov     [eax+ecx+MemoryHeader.preceding_size],ecx
        add     ecx,eax
        mov     [malloc_freelist],ecx
        mov     [ecx+MemoryHeader.size],edx
        mov     [ecx+edx+MemoryHeader.preceding_size],edx
        mov     edx,[eax+FreeMemory.right]
        cmp     edx,eax
        je      update_free_singleton
        mov     [ecx+FreeMemory.right],edx
        mov     [edx+FreeMemory.left],ecx
        mov     edx,[eax+FreeMemory.left]
        mov     [ecx+FreeMemory.left],edx
        mov     [edx+FreeMemory.right],ecx
        jmp     finish_malloc
    update_free_singleton:
        mov     [ecx+FreeMemory.left],ecx
        mov     [ecx+FreeMemory.right],ecx
        jmp     finish_malloc
    use_whole_block:
        mov     edx,[eax+FreeMemory.right]
        cmp     edx,eax
        je      depleted_freelist
        mov     ecx,[eax+FreeMemory.left]
        mov     [ecx+FreeMemory.right],edx
        mov     [edx+FreeMemory.left],ecx
        mov     [malloc_freelist],edx
        jmp     finish_malloc
    depleted_freelist:
        and     [malloc_freelist],0
        jmp     finish_malloc

mfree:
; in: eax - memory block
; out: cf set on error
; preserves: ebx, esi, edi
; note: eax may have value 0 or -1, it should be treated as invalid input then
        test    eax,eax
        jz      mfree_error
        cmp     eax,-1
        je      mfree_error
        sub     eax,sizeof.MemoryHeader
        mov     ecx,[eax+MemoryHeader.size]
        btr     ecx,0
        jnc     mfree_error
        cmp     ecx,sizeof.FreeMemory
        jb      mfree_error
        cmp     [eax+ecx+MemoryHeader.preceding_size],ecx
        jne     mfree_error
        mov     [eax+MemoryHeader.size],ecx
        mov     edx,eax
        sub     edx,[eax+MemoryHeader.preceding_size]
        cmp     edx,eax
        je      no_preceding_block
        test    [edx+MemoryHeader.size],1
        jz      coalesce_with_preceding_block
    no_preceding_block:
        test    [eax+ecx+MemoryHeader.size],1
        jz      coalesce_with_following_block
        mov     ecx,[malloc_freelist]
        jecxz   mfree_init_freelist
        mov     edx,[ecx+FreeMemory.right]
        mov     [eax+FreeMemory.left],ecx
        mov     [edx+FreeMemory.left],eax
        mov     [eax+FreeMemory.right],edx
        mov     [ecx+FreeMemory.right],eax
    mfree_ok:
        mov     [malloc_freelist],eax
        clc
        retn
    mfree_init_freelist:
        mov     [eax+FreeMemory.left],eax
        mov     [eax+FreeMemory.right],eax
        jmp     mfree_ok
    mfree_error:
        stc
        retn
    coalesce_with_preceding_block:
        add     ecx,[edx+MemoryHeader.size]
        test    [edx+ecx+MemoryHeader.size],1
        jz      coalesce_on_both_ends
        mov     [edx+MemoryHeader.size],ecx
        mov     [edx+ecx+MemoryHeader.preceding_size],ecx
        clc
        retn
    coalesce_on_both_ends:
        lea     eax,[edx+ecx]
        add     ecx,[eax+MemoryHeader.size]
        mov     [edx+MemoryHeader.size],ecx
        mov     [edx+ecx+MemoryHeader.preceding_size],ecx
        mov     [malloc_freelist],edx
        mov     ecx,[eax+FreeMemory.left]
        mov     edx,[eax+FreeMemory.right]
        mov     [edx+FreeMemory.left],ecx
        mov     [ecx+FreeMemory.right],edx
        clc
        retn
    coalesce_with_following_block:
        push    ebx
        lea     ebx,[eax+ecx]
        add     ecx,[ebx+MemoryHeader.size]
        mov     [eax+MemoryHeader.size],ecx
        mov     [eax+ecx+MemoryHeader.preceding_size],ecx
        mov     ecx,[ebx+FreeMemory.left]
        mov     edx,[ebx+FreeMemory.right]
        mov     [ecx+FreeMemory.right],eax
        mov     [edx+FreeMemory.left],eax
        mov     ecx,[ebx+FreeMemory.left]
        mov     edx,[ebx+FreeMemory.right]
        mov     [eax+FreeMemory.left],ecx
        mov     [eax+FreeMemory.right],edx
        pop     ebx
        jmp     mfree_ok

realloc:
; in: eax - memory block, ecx = requested size
; out: eax - resized block, ecx = allocated size, on error jumps to out_of_memory (does not return)
; preserves: ebx, esi, edi
        dec     ecx
        and     ecx,(-1) shl 2
        add     ecx,1 shl 2
        jc      out_of_memory
        add     ecx,sizeof.MemoryHeader
        jc      out_of_memory
        sub     eax,sizeof.MemoryHeader
        mov     edx,[eax+MemoryHeader.size]
        and     edx,not 1
        cmp     ecx,edx
        jbe     realloc_retain
        test    [eax+edx+MemoryHeader.size],1
        jnz     realloc_and_copy
        add     edx,[eax+edx+MemoryHeader.size]
        cmp     ecx,edx
        ja      realloc_and_copy
        sub     edx,ecx
        cmp     edx,sizeof.FreeMemory
        jb      append_whole_block
        push    esi edi
        push    ecx edx
        lea     edi,[eax+ecx]
        xchg    ecx,[eax+MemoryHeader.size]
        and     ecx,not 1
        lea     esi,[eax+ecx]
        mov     ecx,[esi+FreeMemory.left]
        mov     edx,[esi+FreeMemory.right]
        mov     [edx+FreeMemory.left],edi
        mov     [ecx+FreeMemory.right],edi
        mov     ecx,[esi+FreeMemory.left]
        mov     edx,[esi+FreeMemory.right]
        mov     [edi+FreeMemory.left],ecx
        mov     [edi+FreeMemory.right],edx
        mov     [malloc_freelist],edi
        pop     edx ecx
        mov     [edi+MemoryHeader.size],edx
        mov     [edi+edx+MemoryHeader.preceding_size],edx
        mov     [edi+MemoryHeader.preceding_size],ecx
        pop     edi esi
        jmp     finish_malloc
    append_whole_block:
        add     edx,ecx
        mov     [eax+edx+MemoryHeader.preceding_size],edx
        xchg    edx,[eax+MemoryHeader.size]
        and     edx,not 1
        add     edx,eax
        mov     ecx,[edx+FreeMemory.left]
        cmp     ecx,edx
        je      depleted_freelist
        mov     edx,[edx+FreeMemory.right]
        mov     [ecx+FreeMemory.right],edx
        mov     [edx+FreeMemory.left],ecx
        mov     [malloc_freelist],ecx
        jmp     finish_malloc
    realloc_retain:
        and     [eax+MemoryHeader.size],not 1
        jmp     finish_malloc
    realloc_and_copy:
        push    esi edi
        lea     esi,[eax+sizeof.MemoryHeader]
        call    malloc_growable
        push    eax ecx
        mov     edi,eax
        mov     eax,esi
        mov     ecx,[esi-sizeof.MemoryHeader+MemoryHeader.size]
        shr     ecx,2
        rep     movsd
        call    mfree
        pop     ecx eax
        pop     edi esi
        retn

if used mcheck

    mcheck:
        pushfd
        pushad
        mov     eax,[malloc_freelist]
        test    eax,eax
        jz      integrity_verified
      verify_freelist:
        mov     ebx,eax
      verify_preceding_blocks:
        mov     ecx,[ebx+MemoryHeader.preceding_size]
        jecxz   preceding_blocks_ok
        sub     ebx,ecx
        mov     edx,[ebx+MemoryHeader.size]
        and     edx,not 1
        cmp     ecx,edx
        je      verify_preceding_blocks
        jmp     internal_error
      preceding_blocks_ok:
        mov     ebx,eax
      verify_following_blocks:
        mov     ecx,[ebx+MemoryHeader.size]
        and     ecx,not 1
        cmp     ecx,sizeof.MemoryHeader
        je      following_blocks_ok
        add     ebx,ecx
        cmp     ecx,[ebx+MemoryHeader.preceding_size]
        je      verify_following_blocks
        jmp     internal_error
      following_blocks_ok:
        mov     edx,[eax+FreeMemory.right]
        cmp     eax,[edx+FreeMemory.left]
        je      verify_next
        jmp     internal_error
      verify_next:
        mov     eax,edx
        cmp     eax,[malloc_freelist]
        jne     verify_freelist
      integrity_verified:
        popad
        popfd
        retn

end if    
To port it to any other OS you only need to update the "valloc" function. So far I have been testing it under Windows, therefore "valloc" is implemented with VirtualAlloc (on Linux you'd do it with mmap, most likely). But I hope to make some DOS versions using it, too. A version for unreal mode is a possibility, although even just a DPMI-based version may be worth considering, as this would allow to run fasmg in DOS using any DPMI implementation (instead of being limited to HX as currently), allowing to use one with virtual memory capabilities, etc.

Also, this very basic implementation does not make use of the "malloc_fixed" and "malloc_growable" hints - it would require a much more sophisticated implementation to make a good use of them, and it probably would not make a noticeable difference anyway. These hints are not really utilized in any port of fasmg, I keep them mostly because they slightly improve readability of the code.

The "mcheck" function does a quite through integrity check of the heap portions accessible through the list of free blocks. It is an optional sanity check, but the best place to call it is after all blocks have been freed (after the "assembly_shutdown" call).
Post 29 Apr 2020, 12:41
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 29 Apr 2020, 13:20
Thanks Tomasz.
all fasmpack was with fasm license only. (I am not interested in my own copyright)
I add fasmg license to its subfolder licenses. That would be enought? Or add it in file header comment?

I would like to think that I develop only preliminary version.
And final ones would be accesible in fasmg official package.
And mine package would contain only copy of it.
So way that fasmg port will not be part of any OS, but downloadable from web within fasmg package.
Post 29 Apr 2020, 13:20
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 29 Apr 2020, 13:28
ProMiNick wrote:
I add fasmg license to its subfolder licenses. That would be enought?
Yes, that would be enough.
Post 29 Apr 2020, 13:28
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 29 Apr 2020, 13:50
Post 29 Apr 2020, 13:50
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 29 Apr 2020, 17:01
The DPMI-based DOS version is ready: https://github.com/tgrysztar/fasmg/tree/master/core/source/dos

The code of fasmg easily fits into 64K segment, so it might be even possible to add an unreal mode support there, but I'm going to leave that for when I am able to play a bit with my vintage PC.
Post 29 Apr 2020, 17:01
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 802
Location: Russian Federation, Sochi
ProMiNick 04 May 2020, 07:57
https://yadi.sk/d/HTs1wxZvp6BmYw updated (fasmg kolibri port for now is still inconsistent so uncompilable)
but its system.inc layer is ready. maybe some portions of kolibri fasm port system.inc will migrate too.

More important kolibri port of fasm now accept all requirement to fasm (in every environment same source will produce same output) - it is happened because of processing path slashes (that previously absent) & because of correct realization of make_timestamp & separating it from get_tickcount (previousle they was messed).
Post 04 May 2020, 07:57
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.