Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dos 21h, function 48h (help on allocating mem.)

387 views
Skip to first unread message

Chad Helfenberger

unread,
Jul 17, 1995, 3:00:00 AM7/17/95
to
I'm writing a few text-mode windowing routines for DOS using turbo c++
and tasm 4.1. First off, I'm using the following formula to determine
how much memory to allocate to store the data which will be overwritten
by the window:

[((SizeX * SizeY) - 1) * 2]
--------------------------- + 1
16

SizeX/SizeY are the size of the window including the corners.
*2 is to include room for attributes.

Will this formula work? It appears to, because I've tested it with a few
different SizeX and SizeY values. The purpose of it is to determine
the minimum # of paragraphs which much be allocated to store the entire
window.

I've traced through my preliminary program and bx (the register function
48h expects the paragraph count to be in) ends up with 12d for a window size
of 10 x 5. when the int 21h is executed it *always* comes back with
ax=0008 (insufficient memory) .. (both in the debugger and out). I should
have *plenty* of memory available for it.

Thanks for any help.


--
!quare


Chad Helfenberger

unread,
Jul 18, 1995, 3:00:00 AM7/18/95
to
cs830927 (di...@csie.ncu.edu.tw) wrote:
: function 4ah:
: ah = 4ah;
: es = the address of the memory block;
: bx = size of memory block(in 16 bytes);

I'm a little confused. The address of what memory block?
--
!quare


gcli...@ulkyvx.louisville.edu

unread,
Jul 18, 1995, 3:00:00 AM7/18/95
to

The one you got from the function 48h call. It's a segment address.
o> --
> !quare
>

cs830927

unread,
Jul 18, 1995, 3:00:00 AM7/18/95
to
Chad Helfenberger (qu...@iglou.iglou.com) 提到:
: I'm writing a few text-mode windowing routines for DOS using turbo c++

: Thanks for any help.


: --
: !quare

before calling int 21h, function 48h, you should calling function 4ah
to resize the memory you program used.

function 4ah:
ah = 4ah;
es = the address of the memory block;
bx = size of memory block(in 16 bytes);

--
[32;35m中央資工 87 級 林正隆
[32;36mEmail: u353...@sparc20.ncu.edu.tw
[32;36m di...@csie.ncu.edu.tw
[m


Chad Helfenberger

unread,
Jul 19, 1995, 3:00:00 AM7/19/95
to
gcli...@ulkyvx.louisville.edu wrote:
: > I'm a little confused. The address of what memory block?

: The one you got from the function 48h call. It's a segment address.

Well in the original message you said to call function 4ah before calling
function 48h. If I call 48h before calling 4ah, I get an error 08 in ax,
where the segment address should be if there is no error. If I call 4ah
before 48h, I don't have a segment address to give it. That's why I am
confused.

--
!quare


gcli...@ulkyvx.louisville.edu

unread,
Jul 20, 1995, 3:00:00 AM7/20/95
to
Sorry if I gave you the wrong advice... It's been a while since I posted
that other message and I guess I forgot. But you're right, if you're
doing the first 4ah call which you have to do before you can do the
first 48h call you need a segment address to give it. You use the
segment of the program PSP. For a .COM file this will be in CS,DS,ES,SS
when the program starts. For a .EXE file it will be in DS and ES until
you load them with some other segment address. The PSP is the
program segment prefix; it has the command line, file FCBs environment
pointer, & etc.

So you could do this:

.data
psp dw 0

.code

start:
mov ax,dgroup
mov ds,ax
mov [psp],es
mov es,ax
...other startup code
mov es,[psp]
mov bx,size requested in paragraphs
mov ah,4ah
int 21h
....after this you should be able to use function 48h

Sorry for the confusion,

David
> --
> !quare
>

Andreas Reiss

unread,
Jul 20, 1995, 3:00:00 AM7/20/95
to
In article DBvq3...@iglou.com,
qu...@iglou.iglou.com (Chad Helfenberger) writes:


>
> I've traced through my preliminary program and bx (the register function
> 48h expects the paragraph count to be in) ends up with 12d for a window size
> of 10 x 5. when the int 21h is executed it *always* comes back with
> ax=0008 (insufficient memory) .. (both in the debugger and out). I should
> have *plenty* of memory available for it.
>

Have you done something like

RESIZE: MOV BX,(OFFSET PROG_END - OFFSET PROG_START)
;FIND OUT HOW BIG THE PROGRAM IS
MOV CL,4 ;TURN THIS VALUE INTO PARAGRAPHS
SHR BX,CL
;
INC BX ;NEEDS 1 MORE TO CATCH OVERFLOW
MOV AH,04AH ;ASK FOR DEALLOCATION OF ALL BUT THIS
INT 021H

without that dos thinks all mem is in use, but its mostly not.
Happy programming

Andreas


---
100....@GermanyNET.de is Andreas Reiss from 47509 Rheurdt

Chad Helfenberger

unread,
Jul 20, 1995, 3:00:00 AM7/20/95
to
gcli...@ulkyvx.louisville.edu wrote:
: So you could do this:

<code fragment deleted>

: Sorry for the confusion,

Hey.. no problem. Thanks for the clarification. One quick question..
It sounds like if I change memory models with this, I'm going to have to do
a lot of work changing stuff around. Am I right?

: David
--
!quare


cs830927

unread,
Jul 20, 1995, 3:00:00 AM7/20/95
to
Chad Helfenberger (qu...@iglou.iglou.com) 提到:

: gcli...@ulkyvx.louisville.edu wrote:
: : > I'm a little confused. The address of what memory block?

: : The one you got from the function 48h call. It's a segment address.

: Well in the original message you said to call function 4ah before calling
: function 48h. If I call 48h before calling 4ah, I get an error 08 in ax,
: where the segment address should be if there is no error. If I call 4ah
: before 48h, I don't have a segment address to give it. That's why I am
: confused.

: --
: !quare

the segment value of PSP of your program is also produced by calling
function 48h. So, if you want more memory, you can reduce the memory
usage of your program.

You can examine the MCB(Memory Control Block) of your program, value of
which is one less than that of PSP. The format of MCB is:

Offset Size Meaning
0 bytes Signature (M or Z, Z for the last MCB)
1 word PID (PSP of owner of this memory block, 0008h: system)
3 word Size (in 16 bytes)
8 name of the program (DOS 5 or higher)

Here is a simple example of function 4ah:

.model tiny ; tasm or masm 6.0
.code
org 100h
begin:
mov ah,4ah ; cs = ds = es = ss = psp in .com file
mov bx,1000h ; 64k (= 4096 * 16)
int 21h ; here we assume no error

mov ah,48h
mov bx,200h ; 512 bytes
int 21h

; add your code here

mov ah, 4ch
int 21h

end begin

Chad Helfenberger

unread,
Jul 20, 1995, 3:00:00 AM7/20/95
to
cs830927 (di...@csie.ncu.edu.tw) wrote:
: the segment value of PSP of your program is also produced by calling

: function 48h. So, if you want more memory, you can reduce the memory
: usage of your program.

cool. I'll see what I can accomplish with this new info. Does it matter
that I am not using a com file?

--
!quare


Glen Blankenship

unread,
Jul 21, 1995, 3:00:00 AM7/21/95
to
Chad Helfenberger (qu...@iglou.iglou.com) wrote:
> It sounds like if I change memory models with this, I'm going to have to do
> a lot of work changing stuff around. Am I right?

I don't think anyone has mentioned yet (at least in this thread) that you
can save yourself the bother of reducing the size of your program's memory
block at runtime, simply by having DOS allocate only as much memory
as your program needs when it loads.

The EXE file header contains two fields that specify how many paragraphs
of memory DOS should allocate (in addition to the size of the EXE image).
The first, exMinAlloc, at offset 0Ah, specifies the minimum number of
additional paragraphs. This is the amount that's needed for the stack,
uninitialized data segments, and so on. The linker calculates this at link
time. The second field, exMaxAlloc, at offset 0Ch, tells DOS the maximum
number of paragraphs the program can use. By default, most linkers set this
field to 0FFFFh.

When DOS loads a program it attempts to allocate a block large enough to
hold the program image + exMaxAlloc paragraphs. If this attempt fails
(and it will if exMaxAlloc=0FFFFh), DOS then checks to see if the largest
available block will accomodate the load image + exMinAlloc. If so, it
allocates that block and loads the program. If not, it fails the load.

By setting exMaxAlloc = exMinAlloc, you can have DOS allocate only as
much memory as your program actually needs when it loads, thus leaving the
remainder free for subsequent allocation at runtime.

There are several ways to adjust the exMaxAlloc field. Microsoft's LINK
has a switch, /CP[ARMAXALLOC], that allows you to specify a setting for
exMaxAlloc. Since the linker won't set exMaxAlloc to a smaller value than
exMinAlloc, using /CP:1 will set exMaxAlloc to the minimum value. Other
vendors' linkers have similar options: check your linker documentation for
details.

MASM also includes the EXEMOD utility, which allows to modify many of the
values in the EXE header of an already-linked program. You can use
EXEMOD rather than re-linking.

And, finally, if neither of those two approaches works for you, you can use
a binary editor to directly patch the file's EXE header. Just set the
field at 0Ch equal to the field at 0Ah.

---
Glen Blankenship
obo...@netcom.com


cs830927

unread,
Jul 21, 1995, 3:00:00 AM7/21/95
to
Chad Helfenberger (qu...@iglou.iglou.com) 提到:

: --
: !quare

when you writr a .exe file, you must note that when the program begins
executing, DS = ES = PSP, and the value of CS and SS, in normal circum-
stances, might not equal to that of PSP

gcli...@ulkyvx.louisville.edu

unread,
Jul 21, 1995, 3:00:00 AM7/21/95
to
In article <DC0y3...@iglou.com>, qu...@iglou.iglou.com (Chad Helfenberger) writes:
> gcli...@ulkyvx.louisville.edu wrote:
> : So you could do this:
>
> <code fragment deleted>
>
> : Sorry for the confusion,
>
> Hey.. no problem. Thanks for the clarification. One quick question..
> It sounds like if I change memory models with this, I'm going to have to do
> a lot of work changing stuff around. Am I right?
>
Hi,

I don't think so. As long as your ProgramEnd segment comes last
you'll be ok. I was just rambling on about ways to ensure this
if you've got multiple source modules.
The only real problem you'll run into is if you
start integrating C code and Assembly code, but then you shouldn't
have to do the function 4ah call because the C runtime system should
do it.

David

> : David
> --
> !quare
>

Chad Helfenberger

unread,
Jul 22, 1995, 3:00:00 AM7/22/95
to
gcli...@ulkyvx.louisville.edu wrote:
: I don't think so. As long as your ProgramEnd segment comes last

: you'll be ok. I was just rambling on about ways to ensure this
: if you've got multiple source modules.

Do you have to resize the block to DOS's original size before you
exit the program? I'm getting memory allocation error (runtime error)
when the program executes function 4ch (int 21). I've traced
through. I have an OpenWindow function that allocates memory.
I have checked to make sure the routine doesn't write stuff out of
the allocated bounds.

CloseWindow frees the allocated memory. Neither (de)allocation causes
an error.. the modify call doesn't either. It's only when I exit the
program... any ideas?
--
!quare


gcli...@ulkyvx.louisville.edu

unread,
Jul 24, 1995, 3:00:00 AM7/24/95
to
In article <DC4y8...@iglou.com>, qu...@iglou.iglou.com (Chad Helfenberger) writes:
> gcli...@ulkyvx.louisville.edu wrote:
> : I don't think so. As long as your ProgramEnd segment comes last
> : you'll be ok. I was just rambling on about ways to ensure this
> : if you've got multiple source modules.
>
> Do you have to resize the block to DOS's original size before you
> exit the program? I'm getting memory allocation error (runtime error)
> when the program executes function 4ch (int 21). I've traced
> through. I have an OpenWindow function that allocates memory.
> I have checked to make sure the routine doesn't write stuff out of
> the allocated bounds.

No, you don't have to resize to DOS's original size. When you exit
DOS automatically deallocates any memory you allocate, just in case
you forget. Although it is good practice to do it yourself.[B


>
> CloseWindow frees the allocated memory. Neither (de)allocation causes
> an error.. the modify call doesn't either. It's only when I exit the
> program... any ideas?

Most memory errors on program exit are because the program trashed
one or more of the DOS arena control blocks by writing outside their
bounds... a lot of times it will hang and say it can't load command.com.
You say you're not doing this, and quite frankly the fact that none of your
deallocations causes an error supports this thesis.
So I'm stymied as to what the problem
could be... however, I do have problems with the V4.5 TD (borland)
wherein it forgets to deallocate memory the program has allocated,
which is a hassle because I have to let the program run to completition
so the deallocate code will run... or I lose the memory. Does your
problem allways occur, or just when the debugger is running?

Sorry I couldn't be much help,

David


> --
> !quare
>

0 new messages