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

Assembly: dynamic memory allocation without malloc and syscalls? [FreeDOS application]

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

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 字节的下一个段落边界以用作堆栈 space。此堆栈的末尾是 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