Yes, this format is older than EXE but still good and used for small
simple programs like the one you write. I suggest don't switch to EXE
unless you have to.
From your posting I see that you are using A86. That's great assembler
(though I'd love to play with A386) and produces COM output as default
so why would you wan't to go through the trouble of making EXE if you
don't have to?
--
ak...@priv5.onetNOSPAM.pl
remove you know what to email
I know much of this, but what I really need to know and what I hope you
can you tell me is: Approximately how long of a source file translates into
a 64Kb executable (I ask this below where my other questions are, so please
answer it there if you do not mind)?
> Yes, this format is older than EXE but still good and used for small
> simple programs like the one you write. I suggest don't switch to EXE
> unless you have to.
>
> From your posting I see that you are using A86. That's great assembler
> (though I'd love to play with A386) and produces COM output as default
> so why would you wan't to go through the trouble of making EXE if you
> don't have to?
Honestly, I really don't want to make it an .EXE. The problems are
that I am nowhere near done (based on the amount of code I've written so far
and what it has gotten me, I think I'll have to write ten times the amount I
have written so far... At a minimum), and I want to be able to use this
program as a template. It's just a text adventure game, but I want to set
it up so that each room, weapon, tool, etc.. is in it's own file and has a
standardized return. This will allow me (or anyone else, if anyone
actually wants it) to create the specific adventure I want, without
requiring me to rewrite the entire program.
I'm not saying this is an original idea or that it has any real merit.
It is just a practice program I am working on.
I asked the original question so I could decide what further questions
I needed answered... Here is what I know I need answers to:
1) Can a .COM use multiple source files as long as there remains only one
actual segment?
2) Approximately how many lines of code will fit into a .COM program? I'm
asking about source code, not executable... I'm sure this varies greatly
because different instructions change into different amounts of executable
code, but I also presume that there is a reasonable point where one says "X
number of lines of code is going to be close to too much".
>2) Approximately how many lines of code will fit into a .COM program? I'm
>asking about source code, not executable... I'm sure this varies greatly
>because different instructions change into different amounts of executable
>code, but I also presume that there is a reasonable point where one says "X
>number of lines of code is going to be close to too much".
Hard to tell... Let's say the average instruction is 4 bytes... Just a
hip-shot. After all we're on near-call code.
Then you can write 16384 lines (assuming one instruction per line) of
code before have to use .EXE
If the average instruction is, say 8 bytes, you have room for 8192
instructions in a .COM file. That's a big piece of code anyway.
But with 65536 bytes code you have NO SPACE for data and stack. Using
only registers and no stack would be virtually impossible IMHO. :-)
One should never say never though.
You also have to consider statc data, like string constants etc. Those
COULD be located in the CODE segment (in the code I mean, we have only
one segment in a .COM application).
So all in all, you need space for code, data (including static vars),
and a small stack (stack less than 1k I assume). All this have to fit
in a single 64k segment. If you need more than 64k you have to switch
to .EXE
Good luck!
Bob.
By the way, has anyone a figure on the average instruction size in a
.COM application?
This cuts to the heart of the matter, I am not sure if this is a stupid
question, but I have to ask anyway... Can I do far jumps in a .COM?
I feel pretty sillly jumping through 5 or 6 labels to get to the actual
jump destination, and going through all these labels like I am doing does
not seem to me like it is very good coding. Is this right or is it
considered OK to go through several labels like that?
Thanks for any info, and for the previous help!
Regards,
Seth
> The problems are
> that I am nowhere near done (based on the amount of code I've written so far
> and what it has gotten me, I think I'll have to write ten times the amount I
> have written so far... At a minimum), and I want to be able to use this
> program as a template. It's just a text adventure game, but I want to set
> it up so that each room, weapon, tool, etc.. is in it's own file and has a
> standardized return.
Good idea! I love text based adventure games. I could be beta tester if
you want.
> This will allow me (or anyone else, if anyone
> actually wants it) to create the specific adventure I want, without
> requiring me to rewrite the entire program.
> I'm not saying this is an original idea or that it has any real merit.
> It is just a practice program I am working on.
> I asked the original question so I could decide what further questions
> I needed answered... Here is what I know I need answers to:
>
> 1) Can a .COM use multiple source files as long as there remains only one
> actual segment?
You mean to write code in few pieces assemble it into obj files and then
link them into COM? The answer is YES but what for? Unless you use
external libraries, then it's a different story.
> 2) Approximately how many lines of code will fit into a .COM program? I'm
> asking about source code, not executable... I'm sure this varies greatly
> because different instructions change into different amounts of executable
> code, but I also presume that there is a reasonable point where one says "X
> number of lines of code is going to be close to too much".
Somebody answered this question already.
I can just say that it depends on your style of programming a lot. To
find out approximately just do the following:
x = a/b*64000
where
x is what you're looking for (number of lines for 64000 COM)
a is number of lines in your program as far
b is your program current size
I hope this helps.
you can still do "JMP xxxx:yyyy" (or the assembler's equivalent) which is
"far" in the sense that it is leaving your current code segment. but
these are usually referred to as Absolute jumps and probably aren't what
you're asking about.
what do you mean by jumping through 5 or 6 labels to reach the actual
destination? are you talking about the 128 byte limitation of conditional
jumps? if so, then an unconditional one can span the whole 64k. if not,
then please clarify. :)
Seth <zekek...@sprintmail.com> wrote:
: This cuts to the heart of the matter, I am not sure if this is a stupid
Well, you can use JMP in a com file. You don't have to jump few times
using conditional jump. If your destination is further than 128 bytes
in code use the following pattern
cmp ax,bx
jnz not_equal ; conditional jump
jmp equal ; unconditional jump
not_equal:
; here you go when it's not equal
;
; some code goes here........
; more than 128 bytes
;
equal:
; here you go when it's equal
do you get it?
if you have problems with simple things you might consider reading some
assembly tutorial. I put few on my page at
www.geocities.com/SiliconValley/lab/1928
> I feel pretty sillly jumping through 5 or 6 labels to get to the actual
> jump destination, and going through all these labels like I am doing does
> not seem to me like it is very good coding. Is this right or is it
> considered OK to go through several labels like that?
> Thanks for any info, and for the previous help!
>
> Regards,
> Seth
>
>
--
Thomas Laguzzi
lag...@mail.dada.it
TLP Homepage
http://tlp.virtualave.net
Seth <zekek...@sprintmail.com> wrote in message
7r4l5n$2v4$1...@oak.prod.itd.earthlink.net...
>Can I do far jumps in a .COM?
Of course you can do a far jump, but where do you wanna jump? :-)
A far jump is a jump to another segment, and because the .COM app is
only one segment you would probably (no, not probably, certainly!)
jump outside the segment and into a "bad" place in memory. Most likely
you'd get a segment violation, or just a lockup.
A near jump is "far enough" for the .COM app. :-))
I don't understand why you have to jump several step in order to get
there... Use a label and jump just like Artur explained. That should
do it. If you can't get it right, please post some error messages and
we'll help you through the jungle. :-)
Regards
Bob
Well, probably because I'm a newbie and don't know enough yet, but I'll
give you the basic reason I have and maybe you can tell me how to better do
what I want to accomplish:
I want to be able to easily add or subtract rooms, weapons, tools,
etc., by merely writing a new module and linking it into the basic program
(maybe with a tiny bit of work on the main file, though I REALLY want to
avoid that). I think that this will help me to create this as a template
since each 'object' will be on it's own and there will be less chance of
various objects getting tangled together, and for their code to start
relying on each other to work correctly without my intending for that to
happen.
Now, about this algorithm: x = a/b*64000
I'm not worried about the length of the program anymore (you said I had
room in your post, and I don't see much point in asking if I'm not going to
listen to the answer), but can I use this to gauge whether or not I am
getting better at writing tight code? I presume so, but I figure I might
as well ask in case there is a better way. Also, is there a standard
answer which people should be able to match (so that their code is
reasonably tight)? Or is there some standard which I can measure myself
against? I don't expect much now since this is only the third program I've
written, but I really want to push myself to write good, tight code. It is
a lot more important to me to write good code than to write 'cool' programs.
Thanks for the help!
Seth
P.S. This is not really a program I intended to release since its really
just for practice, but if you would not mind testing it I'd really
appreciate any feedback (especially on the code)! Thanks again!
Yes, that was my problem, and yes I understand the answer. Thanks!
Thanks, I understand that (see my post dated about 11 hours before
yours), but thanks for the response!
> A near jump is "far enough" for the .COM app. :-))
>
> I don't understand why you have to jump several step in order to get
> there... Use a label and jump just like Artur explained. That should
> do it. If you can't get it right, please post some error messages and
> we'll help you through the jungle. :-)
Thanks Bob, that was explained after the (one time) I asked, and I
understand it (you might notice my posts after Artur's stated this). I
appreciate the help offer, but as soon as I was told that unconditional
jumps were not affected by the 128byte barrier I was having trouble with, I
fixed it. I hope the offer stands if I run into more problems, though!
Again, I appreciate the response, thanks!
Robert,
Please be careful. The entire .com program, code, initialized and
uninitialized data and stack, can not exceed one physical memory
segment. This limits the size to 64K. When I write .com programs, I
use the following program segments: a code segment, a CONST segment, a
data segment and a _BSS segment. I declare all of these in the source
code.
The string constants and variables do not have to be declared in the
code program segment. In fact, if you use the DOS segment structure and
place all uninitialized data in the _BSS or .data? segment, space will
not be allocated by the linker for this data which will make the .com
executable smaller. Of course, you still need to ensure that you have
adequate room for the stack.
Ray
> 1) Can a .COM use multiple source files as long as there remains only one
> actual segment?
The answer is yes. When I write code, I usually have one source
file for every procedure. I also ask myself if this procedure
can be a general purpose procedure that I would reuse. If so,
I write it to support all memory models, assembly each and place
it into .lib files so that I can just link in their .obj files.
The advantage is you can debug your simple procedures one at a
time. Once the code is good, just assemble into a .obj and link
them into the executable. You can leave debug information in if
you are still not 100% sure that the code is solid. Personally,
I just can not see assembling the entire source code again and
again each time.
> 2) Approximately how many lines of code will fit into a .COM program? I'm
> asking about source code, not executable... I'm sure this varies greatly
> because different instructions change into different amounts of executable
> code, but I also presume that there is a reasonable point where one says "X
> number of lines of code is going to be close to too much".
I think you have received your answer else where in this thread.
I would like to say that there are other ways to save on space.
You could have you string data in a file that you read at
runtime. Second, if you get too close to the 64K limit or would
like to implement the easy substitution of scenarios, etc., you
could have each scenario as a stand alone program. You main
program would just load and execute whichever scenario the
player chooses. An idea.
Hope that this information is of some help.
Ray
> Hmm.. COM format is for small programs not exceeeding 64Kb (not source
> but executable). They are loaded into memory exactly as they appear on
> the disk and all code and data has to fit in one segment (64Kb)
> You can't use it if you declare stack or data segment. COM is always
> few hundred bytes smaller than EXE sice it doesn't have header.
Artur,
Please be careful. You can declare a data segment in a .com file. When
I write .com file programs, I declare a code, const, data and
uninitialized data segments. I usually write and link multiple source
code files and use previously assembled .obj files from a library. If
you would like to see how, see my startup assembly language code at
SimTel. Its URL is:
ftp://ftp.simtel.net/pub/simtelnet/msdos/asmutl/strtup10.zip
Lastly, this technique is somewhat assembler dependent. The code was
developed using MASM. It should work equally as well with TASM. I do
not use NASM, a86 or any other assembler so I am not sure if the source
code is compatible or not with those products.
Ray
>I hope the offer stands if I run into more problems, though!
Sure!
I'm learning too! I've not written an instruction in Assembly since
the late 80's so I have a lot to freshen. It's coming back, but slow.
I'm getting old, hard to catch up with the new stuff. Like, the new
Pentium instructions, MMX etc... Would like to try though, some sunny
day... :-)
Bob.
>Please be careful. The entire .com program, code, initialized and
>uninitialized data and stack, can not exceed one physical memory
>segment.
You're right, it was indeed a clumsy reply. :)
Bob.
Seth
Ray, thank you for this information, I really appreciate it! I am
understanding that I can use multiple segments (at least those which you
listed) as long as I do not exceed the 64K constraint. If I am wrong,
please correct me. Your last comment leads me to believe that a seperate
stack is declared for the .COM, is this right? If so what is the default
size and is there a way to change that size (for instance, can I declare the
stack myself, thereby giving it the size I want)?
Thanks!
Seth
I do this with my .EXEs already, but I am very happy to hear that I can
use it for my .COMs!
> I would like to say that there are other ways to save on space.
> You could have you string data in a file that you read at
> runtime. Second, if you get too close to the 64K limit or would
> like to implement the easy substitution of scenarios, etc., you
> could have each scenario as a stand alone program. You main
> program would just load and execute whichever scenario the
> player chooses. An idea.
>
> Hope that this information is of some help.
Ray,
That information is DEFINATELY helpful to me, and both of the ideas are
much better than what I have been doing! I especially like the second idea
and I think I'll use it in my final program, provided I can make everything
work. Not whether the language is able, but whether I am... I do not
mind using ideas which are given to me, but I am dead-set on writing the
code myself. Maybe it's stupid to feel this way, but the point of spending
this time is to learn to program on my own, not to learn to scam others into
programming for me.
I'm VERY interested in learning how to set up the string data in a file
that is read at runtime, could you give me some information about it?
Thanks!
Seth
Yeah, I intend on studying it but I don't think it will be in this
program. Don't get me wrong, I'm going to try, and if I can work it out
then I will use it. I don't expect to get it all figured out before I'm
done with this program, though.
>I would suggest writing your modules as procedures in
> separate files. Than in the main program call this procedure passing to
> it needed parameters. This way you keep your main source file small and
> thus clear to understand. With this method I think you could accomplish
> what you want.
> That's just my idea and may not be the best.
>
I think it's probably the best one for me for right now (though its not
like I know of many other ideas to gauge it against). I'm sure I could
spend twice as much time and maybe be able to implement a better idea, but
the purpose of this program is not perfection, merely education.
>
> No it's only partialy true. It's usually the idea that counts the most
> although using shorter instructions helps.
<snip>
> This is very broad subject. There are a lot of optimization techniques
> and the more of them you use the better. Also a lot depends on the
> initial approach to the problem, I mean the way you write program before
> starting to optimize.
I just got my copy of 'Micheal Abrash's Graphics Programming Black Book
Special Edition', which I purchased for the code optimization stuff (the
rest is just gravy, as far as I'm concerned), and what you say really
mirrors his first rule for building high-performance code: Know where you
are going. I feel like I've just had blinders taken off which only allowed
me to see the instructions and the registers!
> > P.S. This is not really a program I intended to release since its
really
> > just for practice, but if you would not mind testing it I'd really
> > appreciate any feedback (especially on the code)! Thanks again!
>
> It's OK, I could take look at it anyway.
Thanks, I really do appreciate it, I'll send it as soon as it's done.
Please DON'T be gentle!
Seth
Hi Seth,
[snip]
> Well, probably because I'm a newbie and don't know enough yet, but
> I'll give you the basic reason I have and maybe you can tell me how to
> better do what I want to accomplish:
> I want to be able to easily add or subtract rooms, weapons, tools,
> etc., by merely writing a new module and linking it into the basic program
> (maybe with a tiny bit of work on the main file, though I REALLY want to
> avoid that). I think that this will help me to create this as a template
> since each 'object' will be on it's own and there will be less chance of
> various objects getting tangled together, and for their code to start
> relying on each other to work correctly without my intending for that to
> happen.
Here's an approach which seems to meet your criteria. It definately isn't
the only solution, and probably isn't the *best*, but I hope it'll give you
a few ideas.
Your main program allocates a few segments of memory to be used as
buffers (to hold your external modules). Each of the external modules
assembled as a COM file (then later renamed to a different extention so the
user can't accidentally run them from the command-line). The general
template for the external modules is something like....
moduleHeader STRUC
internalName db 13 dup (?) ;change to what-ever length you like
eofMarker db 26d, 26d ;text-file EOF marker (I think!)
moduleType db ? ;is it part of the main game
; engine (ie. a dungeon, item, etc.) or is it a seperate
sub-program (ie. character-generator, map editor)
checkSum dd ? ;if you like
commonProc1 dd ? ;these are filled in by the main
commonProc2 dd ? ; program the module's loaded
internalProc1 dw ? ;these are offsets of procs
internalProc2 dw ? ; within this module
ENDS
.code
ORG 100h
moduleHeader db <'Foo', 26d, 26d, 1, ?, ?, ?, OFFSET proc1, OFFSET proc2>
proc1 PROC
ret
ENDP
proc2 PROC
ret
ENDP
The loader for the external modules wouldn't be terribly complex,
something along the lines of:-
- select a free buffer
- load the module into the selected buffer
- set the 'commonProc' fields in the header.
The "commonProcs" are procs in the main module which you want to make
available to all of the external modules, so that they don't have to be
duplicated in each module seperately, and the "internalProcs" are those
specific to the module.
The one thing to be aware of is that COM files expect to be loaded at
100h. The solution is nothing more difficult than subtracting 10h from the
seg. reg. used to access the module and not accessing the first 100h bytes
there-after, but it caused me a few head-aches the first time I tried it.
Another thing you may wish to consider is to use only one "commonProc",
and one "internalProc", both of which act as dispatchers to the various
sub-routines, similar to the way you set AH before an int 21h to select one
of the sub-fuctions. The down-side is that the program will be a little
slower, but the up-side is that you won't have to change the headers for
every module if you want to add a new function, and the headers themselves
will be smaller.
[snip - what makes for "tight" code? (which I suspect you'll get a flood of
answers for)]
> Seth
>
> P.S. This is not really a program I intended to release since its really
> just for practice, but if you would not mind testing it I'd really
> appreciate any feedback (especially on the code)! Thanks again!
Well, if you want to send me a copy (address below), I'll have a look at
it for you. It couldn't hurt..... well.... much. :-)
-Doomsday
doomsday AT optusnet DOT com DOT au
> I want to be able to easily add or subtract rooms, weapons, tools,
> etc., by merely writing a new module and linking it into the basic program
> (maybe with a tiny bit of work on the main file, though I REALLY want to
> avoid that). I think that this will help me to create this as a template
> since each 'object' will be on it's own and there will be less chance of
> various objects getting tangled together, and for their code to start
> relying on each other to work correctly without my intending for that to
> happen.
I like the solution Doomsday posted but I think for beginner is a little
complicated. I would suggest writing your modules as procedures in
separate files. Than in the main program call this procedure passing to
it needed parameters. This way you keep your main source file small and
thus clear to understand. With this method I think you could accomplish
what you want.
That's just my idea and may not be the best.
> Now, about this algorithm: x = a/b*64000
>
> I'm not worried about the length of the program anymore (you said I had
> room in your post, and I don't see much point in asking if I'm not going to
> listen to the answer), but can I use this to gauge whether or not I am
> getting better at writing tight code?
No it's only partialy true. It's usually the idea that counts the most
although using shorter instructions helps.
> I presume so, but I figure I might as well ask in case there is a better way.
> Also, is there a standard
> answer which people should be able to match (so that their code is
> reasonably tight)?
This is very broad subject. There are a lot of optimization techniques
and the more of them you use the better. Also a lot depends on the
initial approach to the problem, I mean the way you write program before
starting to optimize.
> Or is there some standard which I can measure myself
> against? I don't expect much now since this is only the third program I've
> written, but I really want to push myself to write good, tight code. It is
> a lot more important to me to write good code than to write 'cool' programs.
> Thanks for the help!
>
> Seth
>
> P.S. This is not really a program I intended to release since its really
> just for practice, but if you would not mind testing it I'd really
> appreciate any feedback (especially on the code)! Thanks again!
>
It's OK, I could take look at it anyway.
>
>
--
>I am understanding that I can use multiple segments (at least those
>which you listed) as long as I do not exceed the 64K constraint.
Well, let's put it this way: When a .COM application starts (at 0100h)
CS=DS=SS=ES (All segment registers are the same). If you would put
code or data outside this 64k segment you have to allocate the memory
fill it with code or data and then jump far (if it was code). I'm not
sure if this theory is correct though... If you need code and/or data
in a different segment you should probably go for .EXE which makes
things way easier.
I think it would be possible to load modules from disk into memory
(pre-allocated, or inside the segment) memory and run it from there.
This way you get a kinda home-made overlay manager. :-) It's not
easy though.
>If I am wrong, please correct me. Your last comment leads me to
>believe that a seperate stack is declared for the .COM, is this right?
Because all segment registers have the same value, the stack is also
part of the same 64k segment. SP is initially fffeH so the stack is at
the end of the segment.
Bob.
A bit too advanced fer lil' ole me! ;) Seriously, I get what you are
saying but I think I'd better get a bit more experience before I try
something like that.
> Because all segment registers have the same value, the stack is also
> part of the same 64k segment. SP is initially fffeH so the stack is at
> the end of the segment.
So basically I have as much room for the stack as I leave for it (by
not using up the room with the rest of my program), correct?
> Ray, thank you for this information, I really appreciate it! I am
> understanding that I can use multiple segments (at least those which you
> listed) as long as I do not exceed the 64K constraint. If I am wrong,
> please correct me. Your last comment leads me to believe that a seperate
> stack is declared for the .COM, is this right? If so what is the default
> size and is there a way to change that size (for instance, can I declare the
> stack myself, thereby giving it the size I want)?
Seth,
Yes, the sum of all of your program segments must not exceed one
physical memory segment. Note that the tiny memory option uses
the group directive to place all your segments into one group.
This is what allows means that CS = DS = SS.
Note that many responses to your post confuse physical memory
segments with program segments. Please do not let them confuse
you.
To answer your question on the stack, let me quote part of the
MS-DOS Encyclopedia by Microsoft. The section is title,
"Giving control to the .COM program"
After allocating the largest block of free memory
to the .COM program, MS-DOS builds a PSP. in the
lowest 100H bytes of the block. No difference exists
between the PSP MS-DOS builds for .COM programs and
the PSP it builds for .EXE programs. Also with
.EXE programs, MS-DOS determines the initial values
for the AL and AH registers at this time and then
loads the entire .COM-file image into memory immediately
following the PSP. Because .COM files have no file-size
header fields, MS-DOS relies on the size recorded in
the disk directory to determine the size of the
program image. It loads the program exactly as it
appears in the file, without checking the file's
contents.
MS-DOS then set the DS, ES, and SS segment registers
to point to the start of the PSP. If able to allocate
at least 64 KB to the program, MS-DOS sets the SP
register to offset FFFFH + 1 (0000H) to establish an
initial stack; if less than 64 KB are available for
allocation to the program, MS-DOS sets the SP to 1 byte
past the highest offset owned by the program. In
either case, MS-DOS then pushes a single word of
0000H onto the program's stack for use in terminating
the program.
Finally, MS-DOS transfers control to the program by
setting the CS register to the PSP's segment address
and the IP register to 0100H. This means that the
program's entry point must exist at the very start
of the program's image.
Hopefully, this explains how the stack is created at runtime.
Ray
The way I have it organized in my mind is basically thus: A .COM
program may use multiple *program* segments as long as the total memory used
for all of those program segments combined does not exceed one segment of
*memory* (65,536Kb).
If this is a reasonable way to think of it, so be it, otherwise please
correct me.
> To answer your question on the stack, let me quote part of the
> MS-DOS Encyclopedia by Microsoft. The section is title,
> "Giving control to the .COM program"
>
> After allocating the largest block of free memory
> to the .COM program, MS-DOS builds a PSP. in the
> lowest 100H bytes of the block. No difference exists
> between the PSP MS-DOS builds for .COM programs and
> the PSP it builds for .EXE programs.
Up to here I completely understand.
> Also with .EXE programs, MS-DOS determines the initial values
> for the AL and AH registers at this time and then
> loads the entire .COM-file image into memory immediately
> following the PSP.
Is this saying that it does this with both .EXEs and .COMs? Or should
this read 'Also with .COM programs...'?
> Because .COM files have no file-size
> header fields, MS-DOS relies on the size recorded in
> the disk directory to determine the size of the
> program image. It loads the program exactly as it
> appears in the file, without checking the file's
> contents.
>
> MS-DOS then set the DS, ES, and SS segment registers
> to point to the start of the PSP. If able to allocate
> at least 64 KB to the program, MS-DOS sets the SP
> register to offset FFFFH + 1 (0000H) to establish an
> initial stack; if less than 64 KB are available for
> allocation to the program, MS-DOS sets the SP to 1 byte
> past the highest offset owned by the program. In
> either case, MS-DOS then pushes a single word of
> 0000H onto the program's stack for use in terminating
> the program.
>
> Finally, MS-DOS transfers control to the program by
> setting the CS register to the PSP's segment address
> and the IP register to 0100H. This means that the
> program's entry point must exist at the very start
> of the program's image.
>
> Hopefully, this explains how the stack is created at runtime.
It explains it to me quite well, with the one exception listed above.
Thanks very much!
Regards,
Seth
>Yes, the sum of all of your program segments must not exceed one
>physical memory segment.
Actually, under older versions of DOS there was a way to have a
greater than 64K COM file, but under the latest version of Win95 at
least, it no longer works.
>To answer your question on the stack, let me quote part of the
>MS-DOS Encyclopedia by Microsoft. The section is title,
>"Giving control to the .COM program"
>
[...]
> .EXE programs, MS-DOS determines the initial values
> for the AL and AH registers at this time and then
> loads the entire .COM-file image into memory immediately
> following the PSP. Because .COM files have no file-size
> header fields, MS-DOS relies on the size recorded in
> the disk directory to determine the size of the
> program image. It loads the program exactly as it
> appears in the file, without checking the file's
> contents.
This used to be quite literally true but things have changed. If the
.COM file was 100K, for example, the entire 100K was loaded into a
contiguous chunk of memory, and this is the mechanism by which one
could load a larger program (although the stack would still be
initialized to within the middle of the program). However, this
behavior was changed at some point so that Win95, for example, will
refuse to load a .COM file that is 0ff00h or greater byte long (0ff00h
+ 100h PSP = 64K) A 65279 (0feffh) byte program will load but a 65280
(0ff00h) byte program will not. I don't know exactly when the change
was made, but I recall having tested this behavior under OS/2 2.1,
Windows 3.11, DR-DOS 6.0 (not sure about the version here), Novell DOS
7, and MS-DOS 6.0. My recollection is that it worked under all of
them. I'd be curious to hear which behavior is used under NT and
under more recent versions of OS/2.
And of course the other odd restriction for .COM files is that they
must not start with the instructions "dec bp, pop dx" although it's
not obvious at first why this is so. (And I won't spoil the surprise
for those who would like to try to figure out why!)
Ed