Page 1 of 1

16 bit C Memory Allocation

Posted: Tue Apr 17, 2012 5:13 pm
by VolTeK
I have decided to use C in my operating system. My problem is that i have been wondering, what value does an allocation function return for 16 bit programs? Wouldn't it return a segment and an offset? Does anyone have a link to where i can find information about this, or info?

Re: 16 bit C Memory Allocation

Posted: Tue Apr 17, 2012 11:51 pm
by bubach
IIRC, DOS returned a segment value in ax, so all allocs where 16byte aligned. No offset needed.

Re: 16 bit C Memory Allocation

Posted: Wed Apr 18, 2012 1:06 am
by Combuster
DOS applications came with a variety of assumptions on segment register use. In the simplest case you had CS=DS=ES=SS, which would give you 64k of memory to use in total, with no segmentation overhead. You could safely separate CS and DS for 64k data+heap+stack and 64k code. After that, it becomes important for each pointer to consist of both a segment and an offset if you want more. Also, it was possible with several compilers to explicitly use segments for some pointers, and have others default to the "standard" value for DS, for a custom tradeoff between available memory and speed.

A good allocator has to be aware of all these possibilities and hand out memory from the appropriate areas of memory.

Re: 16 bit C Memory Allocation

Posted: Wed Apr 18, 2012 6:13 am
by qw
Google for "memory model". In the NASM manual it is pretty well explained.

Further, it depends. The return value of malloc() may be a near (offset only) or far (segment address and offset) pointer, depending on the memory model, but the return value of DOS int 21H function 48H is a segment address only.

Roel

Re: 16 bit C Memory Allocation

Posted: Wed Apr 18, 2012 10:43 am
by bubach
Found some source on how it's done here:
http://maven.smith.edu/~thiebaut/ArtOfA ... EADING5-10

Re: 16 bit C Memory Allocation

Posted: Wed Apr 18, 2012 2:13 pm
by VolTeK
My Question is, what does the 16 bit malloc return, if its an offset how would the segment work then? My memory manger in assembler returns a segment with a 0 offset. Would i return the far pointer?

Combuster wrote: DOS applications came with a variety of assumptions on segment register use. In the simplest case you had CS=DS=ES=SS, which would give you 64k of memory to use in total, with no segmentation overhead. You could safely separate CS and DS for 64k data+heap+stack and 64k code. After that, it becomes important for each pointer to consist of both a segment and an offset if you want more. Also, it was possible with several compilers to explicitly use segments for some pointers, and have others default to the "standard" value for DS, for a custom tradeoff between available memory and speed.

A good allocator has to be aware of all these possibilities and hand out memory from the appropriate areas of memory.
Sorry if i misunderstand your point, but do you mean return the segment and offset?

Re: 16 bit C Memory Allocation

Posted: Wed Apr 18, 2012 2:41 pm
by Yoda
VolTeK wrote:My Question is, what does the 16 bit malloc return...
DOS (int 21h) memory management functions 48h/49h/4Ah work with paragraphs and return only segment of allocated memory block. The memory block is always aligned by paragraph.

Re: 16 bit C Memory Allocation

Posted: Wed Apr 18, 2012 2:46 pm
by Combuster
what does the 16 bit malloc return
Never the single 16-bit number the call to DOS returns:

If the pointer type is near, then malloc must return only an offset and make sure the "discarded" segment equals DS, and error when the first 64k is used up. If the pointer type is far then malloc must return a segment and an offset (i.e. two 16-bit numbers), where the offset + allocated length < 64k, and allow a larger heap which is satisfied by consistently returning offset=0 with an appropriate segment value.

Which means there are at least two functionally different backends to malloc possible based on the compiler's assumptions, and the better compilers of the day will have needed multiple implementations to support the user's choice of far-near mixtures.

Re: 16 bit C Memory Allocation

Posted: Wed Apr 18, 2012 3:08 pm
by VolTeK
Combuster wrote:Never the single 16-bit number the call to DOS returns:

If the pointer type is near, then malloc must return only an offset and make sure the "discarded" segment equals DS, and error when the first 64k is used up. If the pointer type is far then malloc must return a segment and an offset (i.e. two 16-bit numbers), where the offset + allocated length < 64k, and allow a larger heap which is satisfied by consistently returning offset=0 with an appropriate segment value.

Which means there are at least two functionally different backends to malloc possible based on the compiler's assumptions, and the better compilers of the day will have needed multiple implementations to support the user's choice of far-near mixtures.
Thank you,

Thank you all for your responses.

Re: 16 bit C Memory Allocation

Posted: Wed Apr 18, 2012 3:25 pm
by Yoda
@Combuster,
All that you wrote belongs to 16 bit memory models: tiny, small, medium, compact, large, huge. Nevertheless developer should keep in mind the following details: 1) C-library malloc is frontend to DOS memory management. So at the OS level memory management works only with paragraphs and segments. Of course, the segment is converted to pointer valid in used memory model. 2) Programmer may explicitly use far pointers, so even in tiny model you may use large blocks of allocated memory. In TurboC there were provided memory model independed functions: farmalloc, farfree, etc.

Re: 16 bit C Memory Allocation

Posted: Mon Apr 23, 2012 10:27 pm
by miker00lz
i will add that there is also the halloc function in some DOS C compilers that will return "huge" pointers if you needed more than 64 KB for a single array. using this and explicitly declaring the array as huge, i.e. char __huge *whatever meant that you could use super-large arrays even if your whole program wasn't compiled with the huge memory model.

some implementations were a bit broken, though. i always broke up > 64 KB arrays into smaller chunks like 1 KB, which i'd manage by making custom functions to call the DOS int 21h, function 48h to allocate and return a segment to populate an array of far pointers. then i'd write macros to normalize the offsets into the array for reading and writing.

i do not miss the days of DOS programming that much, i can say that for sure. at least we were often forced to be creative, which in the long run certainly can't hurt. :)