Question

I am writing my first TSR. I know I have to use function 31H of INT 21H. When i looked it up, I found out that the value in DX is the "memory size in paragraphs". I don't know how to calculate that and GOOGLE didn't help. I want to know how can I calculate the memory size in paragraphs of my code.

i just found this

mov dx, OFFSET Install ; DX = bytes in resident section
mov cl, 4
shr dx, cl ; Convert to number of paragraphs
inc dx ; plus one
mov ax, 3100h ; Request Function 31h, error code=0
int 21h ; Terminate-and-stay-resident

Why is there a plus one? And know should i assume that a paragraph = offset*16 and that is it?

Was it helpful?

Solution

Paragraphs are 16-byte increments of memory. To figure out your program size dynamically as your program runs will depend in part on the language used for programming, model of the program and the segment structure in use. Generally what you would do is to arrange your link map to place a nearly empty (maybe a 1 byte allocated) segment at the end of your total program image. The the single unused but allocated byte is given a symbol that you can reference at run time.

Since, when programming in a 16-bit environment, segment addresses increment on paragraph boundaries the process to figure out your programs run time size is to subtract the segment of our programs load time PSP (program segment prefix) from the "segment" part of the address of the unused byte variable mentioned above. The difference is the number of paragraphs to ask DOS to keep loaded when you go TSR.

Note it can be very useful to carefully study the map file produced by the linker when your program is built. At least you need to check that the marker segment that you setup at the end of the image is indeed the last thing in image.

Note also that some programming environments may already have marker segments setup for just this purpose within their programming template.

OTHER TIPS

In your example, the label Install refers to the end of your TSR's resident portion within your process. By taking the label, shifting right by four, and incrementing the result, you effectively divide by 16 (the size of a paragraph) and add 1 to insure a partial last paragraph is accounted for.

There is one case where this calculation is too pessimistic: If the label Install is on a paragraph boundary, your example will allocate one more paragraph than needed, which is unused. To improve upon that, do this instead:

        mov dx, offset Install
        add dx, 15
        mov cl, 4
        shr dx, cl
        mov ax, 3100h
        int 21h

(Note that this has a slightly larger encoding than your original.)

Another issue is that the calculation can be done at build time instead of at run time. That is too arcane for most programs, indicated by the fact that the mov \ shr combination is fairly common in 86-DOS programs. It may need some tricky handling, depending on the assembler. Here's an answer to a different question, with an example of build-time calculation written for NASM: https://stackoverflow.com/a/57762635/738287

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top