问题
My question is about the logic of dynamic memory allocation in assembly (particularly, MASM). There are lot of articles on this topic and all of them rely on the use of malloc or brk. However, according to my understanding, malloc as a part of C language must (or could) be certainly written on assembly. Idem for brk, because it's a part of the operating system, thus also written on C which can be replaced 1 to 1 by assembly. Very very long time ago I have seen an article in PCMag about dynamic memory allocation in MS-DOS using pure asm. Unfortunately, I have lost all the traces of this wonderful piece of writing. Now I'm working with FreeDOS (precisely bootable FreeDOS flash card) and wondering how to proceed if someone decides to write his own memory allocator? What is the starting point and the logic of memory allocation without relying on OS mechanisms?
回答1:
When DOS loads a .COM program, it allocates all of the memory available in the 640KB area (below 0a000h:00000h) to the program, and the program can manage its own memory. If it is desired to use MSDOS memory management, the program first has to release the memory using INT 21H, AH=49H, ES=segment, BX=# paragraphs
. It can then use INT 21H, AH=48H, BX=# paragraphs
, to allocate memory.
As noted in the comments, an .EXE program may or may not allocate all of the memory in the 640KB area.
Example .COM assembly code, to release, and then allocate all available memory. MSDOS will generally consume 16 bytes for its overhead. In this example, BX
is set to the end of the code, then set to the next paragraph boundary that is 256 bytes past the end of the code to use as stack space. The end of this stack is the base of the memory released by the INT 21H, AH=4AH
call.
.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
来源:https://stackoverflow.com/questions/56799938/assembly-dynamic-memory-allocation-without-malloc-and-syscalls-freedos-applic