Author Topic: Reallocating memory with int 21h  (Read 4348 times)

untio

  • Regular Member
  • *
  • Posts: 11
Reallocating memory with int 21h
« on: May 12, 2013, 12:19:32 AM »
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:

Code: [Select]
;--------------------------------
;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.

Gunther

  • Member
  • *****
  • Posts: 3585
  • Forgive your enemies, but never forget their names
Re: Reallocating memory with int 21h
« Reply #1 on: May 12, 2013, 01:00:05 AM »
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:
Code: [Select]
;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
Get your facts first, and then you can distort them.

untio

  • Regular Member
  • *
  • Posts: 11
Re: Reallocating memory with int 21h
« Reply #2 on: May 12, 2013, 05:45:35 AM »
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.




MichaelW

  • Global Moderator
  • Member
  • *****
  • Posts: 1209
Re: Reallocating memory with int 21h
« Reply #3 on: May 12, 2013, 11:15:59 AM »
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;

Code: [Select]
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:
Code: [Select]
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.
Well Microsoft, here’s another nice mess you’ve gotten us into.

untio

  • Regular Member
  • *
  • Posts: 11
Re: Reallocating memory with int 21h
« Reply #4 on: May 12, 2013, 09:14:08 PM »
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:
Code: [Select]
.STACK 2048

.DATA?
  MODOVIDEO DB ?
  PAGINAVIDEO DB ?

Into:
Code: [Select]
.DATA?
  MODOVIDEO DB ?
  PAGINAVIDEO DB ?

.STACK 2048

And I have changed my macro to:

Code: [Select]
;--------------------------------
;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.

dedndave

  • Member
  • *****
  • Posts: 8789
  • Still using Abacus 2.0
    • DednDave
Re: Reallocating memory with int 21h
« Reply #5 on: May 12, 2013, 11:29:53 PM »
you can use the .DOSSEG directive to control the order of segments
Code: [Select]
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
Code: [Select]
        .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

untio

  • Regular Member
  • *
  • Posts: 11
Re: Reallocating memory with int 21h
« Reply #6 on: May 13, 2013, 12:01:12 AM »
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.

dedndave

  • Member
  • *****
  • Posts: 8789
  • Still using Abacus 2.0
    • DednDave
Re: Reallocating memory with int 21h
« Reply #7 on: May 13, 2013, 12:22:01 AM »
the masm manual says it has a period
but, it seems to build either way