Hi,
First of all, thanks for reading this stuff.
I am writing a msdos program that needs to assign memory dinamically. I know that previously I must reduce the memory assigned to my program. Then, i have written this macro that is just at the startup of the program:
;--------------------------------
;AJUSTA LA MEMORIA USADA POR EL
;PROGRAMA AL MINIMO NECESARIO.
;ES NECESARIO PARA PODER USAR
;MEMORIA DINAMICA YA QUE AL
;PRINCIPIO NO HAY MEMORIA LIBRE
;PORQUE EL SISTEMA LA ASIGNA TODA
;AL PROGRAMA.
__AJUSMEM MACRO
MOV BX, SS
MOV AX, ES
SUB BX, AX
MOV AX, SP
SHR AX, 4
ADD AX, 2 <------
ADD BX, AX
MOV AH, 4AH
INT 21H
ENDM __AJUSMEM
;--------------------------------
My doubt is that (in the line with the arrow) I have seen in all the internet examples simply an INC AX, but if I use only inc the program seems to work but when finishes msdos hangs.
My question is if this method is correct or I shall need in some future add 3, 4 or another number to AX. Or I am wrong.
Thanks in advance.
Hi untio
here is one procedure (TASM syntax) which will resize your DOS memory during runtime for later new allocation. You should call it in an early program stage:
;ResMem
;Task: Resize the program's memory block for later allocation.
;Input: None
;Output: cf = 0 ===> success, memory block resized
; cf = 1 ===> failure
;Uses: DOS Interrupt 21h
ResMem proc near
push ax
push bx
mov ax, sp ; ss:sp -> end of program
shr ax, 4
mov bx, ss
add bx, ax
inc bx ; bx = first paragraph beyond program
mov ax, es ; es:0000 -> first program paragraph
sub bx, ax ; bx = program size in paragraphs
mov ah, 4ah ; FUNCTION: resize memory block
int 21h ; transfer to DOS
@@10:
pop bx
pop ax
ret
ResMem endp
I hope that helps a bit.
Gunther
Hi,
First, thanks for your answer. But it doesn't work with my program. I adjoint my full code to this post.
Thanks once more.
Assembling with ML 6.15 using ml /W3 /c:
DRIVES.ASM:
DRIVES.ASM(16) : error A2179: structure improperly initialized
DRIVES.ASM(16) : error A2008: syntax error : in structure
DRIVES.ASM(34) : error A2006: undefined symbol : MARCODRIVES
Fix was to change:
MARCODRIVES MARCO ?
To:
MARCODRIVES MARCO <>
PANTALLA.ASM: No warnings, no errors
MILIB.ASM: No warnings, no errors
MAIN.ASM: No warnings, no errors
Linking with Link16 from the MASM32 distribution using:
\masm32\bin\link16 /INFORMATION /MAP MAIN.OBJ MILIB.OBJ DRIVES.OBJ PANTALLA.OBJ;
C:\MASMDOS\untio>\masm32\bin\link16 /INFORMATION /MAP MAIN.OBJ MILIB.OBJ DRIVES.
OBJ PANTALLA.OBJ;
Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994
Copyright (C) Microsoft Corp 1984-1993. All rights reserved.
**** PARSING DEFINITIONS FILE ****
**** PASS ONE ****
MAIN.OBJ(MAIN.ASM)
MILIB.OBJ(MILIB.ASM)
DRIVES.OBJ(DRIVES.ASM)
PANTALLA.OBJ(PANTALLA.ASM)
**** SEARCHING LIBRARIES ****
**** ASSIGNING ADDRESSES ****
1 segment "_TEXT" class "CODE" length 2b6H bytes
2 segment "_DATA" class "DATA" length 0H bytes
3 segment "STACK" class "STACK" length 800H bytes
4 segment "_BSS" class "BSS" length 15H bytes
5 segment "CONST" class "CONST" length 18H bytes
**** PRINTING MAP FILE ****
**** PASS TWO ****
MAIN.OBJ(MAIN.ASM)
MILIB.OBJ(MILIB.ASM)
DRIVES.OBJ(DRIVES.ASM)
PANTALLA.OBJ(PANTALLA.ASM)
**** WRITING DOS EXECUTABLE ****
And here is the MAP file:
Start Stop Length Name Class
00000H 002B5H 002B6H _TEXT CODE
002B6H 002B6H 00000H _DATA DATA
002C0H 00ABFH 00800H STACK STACK
00AC0H 00AD4H 00015H _BSS BSS
00AD6H 00AEDH 00018H CONST CONST
Origin Group
002B:0 DGROUP
Address Publics by Name
0000:026A DIBUJARFONDO
0000:0216 DIBUJARMARCO
0000:02A9 DIBUJARPANTALLA
0000:01FA DIBUJARPLANOMARCO
0000:028F DIBUJARTITULO
0000:01DA DIBUJARVERTICALMARCO
0000:0134 INICIARDRIVES
0000:00EB PRINTENMEDIO
0000:0088 PRINTSTR
0000:0060 SETMEM
0000:0058 ZEROMEMORY
Address Publics by Value
0000:0058 ZEROMEMORY
0000:0060 SETMEM
0000:0088 PRINTSTR
0000:00EB PRINTENMEDIO
0000:0134 INICIARDRIVES
0000:01DA DIBUJARVERTICALMARCO
0000:01FA DIBUJARPLANOMARCO
0000:0216 DIBUJARMARCO
0000:026A DIBUJARFONDO
0000:028F DIBUJARTITULO
0000:02A9 DIBUJARPANTALLA
Program entry point at 0000:0000
Segments 5
Groups 1
Bytes in symbol table 1921
As you can see the stack is not at the end of the program, although for your purposes I think you can discard the BSS and CONST segments without problems.
When you convert the calculated size in bytes to a size in paragraphs with a SHR 4, you are shifting 4 bits out of the value. If these 4 bits were 0000b then no problem, otherwise your calculated size in paragraphs is one paragraph too small. The normal way of correcting for this is to add one paragraph, and this is the reason for the INC AX you have seen.
Hi,
First of all, thanks to MichaelW for his answer and for give me the clue.
The problem was with the bss segment. It was after the stack. I have changed this:
.STACK 2048
.DATA?
MODOVIDEO DB ?
PAGINAVIDEO DB ?
Into:
.DATA?
MODOVIDEO DB ?
PAGINAVIDEO DB ?
.STACK 2048
And I have changed my macro to:
;--------------------------------
;AJUSTA LA MEMORIA USADA POR EL
;PROGRAMA AL MINIMO NECESARIO.
;ES NECESARIO PARA PODER USAR
;MEMORIA DINAMICA YA QUE AL
;PRINCIPIO NO HAY MEMORIA LIBRE
;PORQUE EL SISTEMA LA ASIGNA TODA
;AL PROGRAMA.
__AJUSMEM MACRO
MOV BX, SS
MOV AX, ES
SUB BX, AX
MOV AX, SP
SHR AX, 4
INC AX
ADD BX, AX
MOV AH, 4AH
INT 21H
ENDM __AJUSMEM
;--------------------------------
And now it runs right.
The problem was in that bss segment was after than the stack segment.
Once more, thanks a lot.
Cheers.
you can use the .DOSSEG directive to control the order of segments
Start Stop Length Name Class
00000H 00020H 00021H _TEXT CODE
00022H 0002FH 0000EH _DATA DATA
00030H 00031H 00002H _BSS BSS
00040H 0083FH 00800H STACK STACK
.MODEL Small
.STACK 2048
.DOSSEG
.386
OPTION CaseMap:None
;####################################################################################
.DATA
s$Msg db 'Hello World !',24h
;************************************************************************************
.DATA?
label2 dw ?
;####################################################################################
.CODE
;************************************************************************************
_main PROC FAR
mov ax,@data
mov ds,ax
mov dx,offset s$Msg
mov ah,9
int 21h
mov ax,4C00h
int 21h
_main ENDP
;####################################################################################
END _main
Hi,
Thanks to dedndave. I think that is better to use DOSSEG and put the directive of the stack at the beginning.
Only a comment: in my version of tasm DOSSEG is without the dot.
Thanks and cheers.
the masm manual says it has a period
but, it seems to build either way