News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

search and print

Started by Pokerice, May 28, 2014, 03:03:38 PM

Previous topic - Next topic

MichaelW

A segment is not necessarily 64KB. The maximum is 64KB, but a segment could be as small as 16 bytes.

For a .COM program DOS allocates all available memory. For an .EXE program DOS allocates enough memory to contain the program image and the PSP, plus any additional memory specified in the EXE header.
Well Microsoft, here's another nice mess you've gotten us into.

Gunther

Quote from: MichaelW on May 29, 2014, 05:40:36 PM
For a .COM program DOS allocates all available memory. For an .EXE program DOS allocates enough memory to contain the program image and the PSP, plus any additional memory specified in the EXE header.

Right, but EXE programs are often very memory hungry, too. So it's necessary to shrink the memory for the EXE if you need a dynamic buffer during run time.

Gunther 
You have to know the facts before you can distort them.

dedndave

for most procedures that you write, you will not use far calls
if you type a procedure as far, the assembler will use a far call automatically
one place you may see far procedures is if you decide to revector an interrupt
another is if you write a device driver
in your own code, you might use far code segments in a Medium or Large memory model program

http://en.wikipedia.org/wiki/Intel_Memory_Model

in a Small or Compact model program, all code is in the same segment
so, procedures can generally be near

it's hard to write a program that needs more than 64 Kb of code - lol
not to say it hasn't been done
but, you won't do it in a few days   :biggrin:
you are more likely to use multiple data segments

FORTRANS

Hi,

Quote from: Pokerice on May 29, 2014, 01:16:36 PM
With that being said, can you use PROC NEAR for some code and PROC FAR for others?

   Yes, but as Dave said, it is not often that you would want to.
Maybe if you wrote a subroutine library or some such.

Quote
Also, regarding to the segments, do some memory block just get automatically allocated as a certain segment or is it always a specific memory block? Say for DOS, since only one segment,
does it just generate 64kb of memory randomly for your program to use?

   Usually DOS will load your program in the first available memory.
If you have more than one segment in your program, you can
specify the load order, but they will normally be loaded one after
another with no wasted space.  (Give or take.)

Quote from: MichaelW on May 29, 2014, 05:40:36 PM
For a .COM program DOS allocates all available memory. For an .EXE program DOS allocates enough memory to contain the program image and the PSP, plus any additional memory specified in the EXE header.

   The default for either a *.COM or *.EXE program is to allocate
all memory to the program.  There are LINK options to limit memory
to a lesser value (and programs to edit the EXE header to do the
same thing), but I have seen very few programs that actually do
that.

Quote from: Gunther on May 29, 2014, 08:16:33 PM
Right, but EXE programs are often very memory hungry, too. So it's necessary to shrink
the memory for the EXE if you need a dynamic buffer during run time.

   I wrote a program using a variable sized buffer that just uses
the memory following the program without deallocating/reallocating
the memory.  I just set a segment register to the end of the program,
and incremented it for each additional data item.  Use information
from the PSP to locate the end of the memory allocated to the
program.  (And have a whole bunch of fun when your {my} math
does not add up.)  I think the shrink/allocate paradigm is a hold-over
from C programming.  Or it could be that I am just lazy.

Quote from: dedndave on May 29, 2014, 08:46:30 PM
you are more likely to use multiple data segments

   Yeah.  Up to a few thousand 48 byte "fake" segments in the
above mentioned program.  I have also written programs that
had data arrays that exceeded the normal segment limits and
thus required more than one data segment.

Regards,

Steve N.

Gunther

Steve,

Quote from: FORTRANS on May 29, 2014, 10:36:05 PM
I think the shrink/allocate paradigm is a hold-over
from C programming.  Or it could be that I am just lazy.

in other words, mostly for blended code EXEs (C, Pascal, BASIC + assembly language).

Gunther
You have to know the facts before you can distort them.

dedndave

compiled code might well set up the EXE header so it doesn't allocate everything

DOS was relatively easy to play with
you can open debug and dump the memory, starting at the 0:0, if desired

as you dump, you can see...
the interrupt vector table
the BIOS data area
resident DOS (msdos.sys, io.sys, resident part of command.com)
your device drivers (link listed)
and, finally, the PSP for debug

each block of memory is prefaced with a heap allocation block
it's a 16-byte (paragraph) of info linking to the next heap block
as you play with the memory free/allocate functions, you can see the heap allocation blocks change

dedndave

in the BIOS data area, there is a variable that tells how much memory is available
when a TSR installs itself high in memory, it might calculate a new top of memory segment and update the variable
so, you can see that up high, too
if you wanted to free and allocate memory - good idea to consult this variable, first   :P

Pokerice

Thank you everyone, it is becoming clearer to me now but one thing still confuses me greatly :icon_redface:. I thought that win32 runs with a flat memory model. The memory models shown in http://en.wikipedia.org/wiki/Intel_Memory_Model seemed to be segmented. So does that mean I can choose to write my code with either flat memory model or segmented?

I understand that basically flat memory model is just making the memory appear to be one continuous block and segmented is just splitting them into sections and accessing them with register and offset(a way to access more memory). So how come I can write using segmented memory model if win32 uses flat memory model?(while using a virtual machine running windows xp 32bit)  Like the "print and search" code I was writing, that is definitely segmented memory model, right?

Could someone explain it kindly and give some examples as to writing what programs in what OS belongs to which memory model. I am sorry for asking so many questions but there seems to be gaps in my knowledge or something I learnt is incorrect.

Gunther

Hi Pokerice,

your questions are not so easy to answer.

  • A DOS program - and your application is one - must use the segemented memory and is limited to see only 1 MB of memory, although you've installed more. It can't see that memory. That has to do with the address generation in Real Mode.
  • To use the FLAT memory model - sometimes called the 32-bit COM model - your application has to be a native 32-bit Windows application. You must use the Windows API and your application must have good manners.
  • With a lot of tricks, your DOS program can use some DPMI services and as a native 32-bit DPMI client, it can use for a while the 32-bit FLAT memory. If you're interested in these aspects, you'll find examples here and here. But to say it clear: That kind of programming style is to hard for a beginner.

Gunther
You have to know the facts before you can distort them.

dedndave

yes - that wiki page on segmented memory models applies to 16-bit DOS programs
as Gunther mentioned, the flat model is used for windows

MichaelW

Quote from: FORTRANS on May 29, 2014, 10:36:05 PM
The default for either a *.COM or *.EXE program is to allocate
all memory to the program.  There are LINK options to limit memory
to a lesser value (and programs to edit the EXE header to do the
same thing), but I have seen very few programs that actually do
that.

What I recall is that the "default" EXE header values effectively specify all available memory.
Well Microsoft, here's another nice mess you've gotten us into.

Pokerice

I think i get the gist of it now. And indeed those examples Gunther provided are more than what I can digest. :lol: Going to avoid them for now. Thanks for the help everyone! :biggrin:

Gunther

Hi Pokerice,

Quote from: Pokerice on May 30, 2014, 05:42:06 PM
And indeed those examples Gunther provided are more than what I can digest. :lol: Going to avoid them for now. Thanks for the help everyone! :biggrin:

I wouldn't say that so strict. If you're willing to go that way, you must simply read and learn a lot of new stuff. You should be familiar with the DOS Interrupts for memory management and with such things like DPMI (DOS Protected Mode Interface). That'll work.

Gunther
You have to know the facts before you can distort them.

FORTRANS

#28
Hi,

   Okay, one can display the data in the *.EXE header with EXEMOD.EXE
program that came with (at least) MASM version 5.0.  I looked in
the MASM32\BIN, and didn't find it there.  I now see an EXEHDR.EXE
in MASM 6.0, but did not use it.

   Anyway, I wrote an EXEHDR.EXE that only prints out exMinAlloc,
exMaxAlloc, and exCheckSum values as documented in the MS-DOS
5.0 Programmer's Reference.  Attached with some example output.
Amusingly I tried it on itself, and it has a bad exMinAlloc value.  Good
old Microsoft tools.  The example output also shows that many programs
do not have a valid checksum.

Cheers,

Steve N.