汇编:没有malloc和syscall的动态内存分配? [FreeDOS应用程序]

时间:2019-06-28 01:19:19

标签: assembly dos heap-memory dynamic-memory-allocation x86-16

我的问题是关于程序集(特别是MASM)中动态内存分配的逻辑。关于此主题的文章很多,所有文章都依赖于malloc或brk的使用。但是,根据我的理解,必须(或可以)将malloc作为C语言的一部分,用汇编语言编写。等同于brk,因为它是操作系统的一部分,因此也写在C上,可以用汇编1对1替换。很久以前,我在PCMag中看到了一篇有关使用纯asm在MS-DOS中进行动态内存分配的文章。不幸的是,我已经失去了这段精彩作品的所有痕迹。现在,我正在使用FreeDOS(可精确引导的FreeDOS闪存卡),并且想知道如果有人决定编写自己的内存分配器该如何进行?不依赖操作系统机制的内存分配的起点和逻辑是什么?

1 个答案:

答案 0 :(得分:6)

当DOS加载.COM程序时,它会将640KB区域(0a000h:00000h以下)中的所有可用内存分配给该程序,并且该程序可以管理自己的内存。如果需要使用MSDOS内存管理,则程序首先必须使用INT 21H, AH=49H, ES=segment, BX=# paragraphs释放内存。然后,它可以使用INT 21H, AH=48H, BX=# paragraphs来分配内存。

如评论中所述,.EXE程序可能会或可能不会分配640KB区域中的所有内存。

.COM汇编代码示例,以释放然后分配所有可用内存。 MSDOS通常会消耗16个字节的开销。在此示例中,BX设置为代码的末尾,然后设置为下一个段落边界,该边界位于代码末尾之后256字节,以用作堆栈空间。该堆栈的末尾是INT 21H, AH=4AH调用释放的内存的基础。

        .286
        .model  tiny,c
        .code
        org     0100h
;       cs,ds,es,ss = program segment prefix, sp = 0fffeh
start:  mov     bx,offset cdend         ;set bx=end stack
        add     bx,0010fh
        and     bx,0fff0h
        mov     sp,bx                   ;sp = new end of stack
        mov     cl,4                    ;release memory
        shr     bx,cl
        mov     ax,04a00h
        int     21h
        mov     ax,04800h               ;set bx = available memory
        mov     bx,0ffffh
        int     21h
        mov     ax,04800h               ;allocate all of it
        int     21h                     ; returns segment in ax
exit:   mov     ax,04c00h               ;exit
        int     21h
cdend:
        end     start