Hello World as a COM file
Time to really shrink your code. In order to do this, we need to know where the wasted space is. If you take the Hello World example we have gone over dozens of times, you know the resulting file is just under 2k bytes. (If you think that is big, try to write Hello World in C or C++ - in class we found these were roughly 150k and 180k respectively). But can we go smaller? The answer is yes, and here is why.
The first reason why our file was nearly 2k is the fact that we were storing all that debugging information in the file. We really don't need to keep all of it once we know the file works. But this was only part of the problem.
When you create an .EXE program, there is a header attached to your file. For the programs we are writting most of these values will be zero. The only important field in the header is the information about segments other than the code segment. If we decide to use only one segment, then we can get rid of all of this header information. Programs that do this are called .COM files.
When DOS loads a program into memory, it creates a program segment prefix (PSP). The contents of this prefix are not important for now, but just understand that information the operating system needs later is stored in it. This prefix is the first 100h bytes of every program (which is why your debugger starts as cs:0100). When you create a .COM file, it assumes that it will be loaded to the first byte cs:0000 which will then conflict with the PSP. To get around this we can use the ORG directive to move the starting location of our program to cs:01000.
But wait! We just said that a .COM program must only use one segment. What do we do with our data segment and our stack? Simple, lump them all together. Below a .COM version of the Hello World file.
TITLE hw_com.asm ;======================================================================= ; Hello World application - prints "Hello World" to the screen ;======================================================================= ;Some Useful Constants LF EQU 0Ah CR EQU 0Dh _TEXT SEGMENT USE16 BYTE PUBLIC 'CODE' ASSUME cs:_TEXT, ds:_TEXT, es:_TEXT, ss:_TEXT ORG 100h ; required for .COM files Start: jmp Begin myString DB "Hello World", CR, LF, "$" Begin: push cs ; set DS to point to our data segment pop ds mov ah, 09h ; function: print string $ terminated mov dx, OFFSET myString ; pointer to string int 21h mov ax, 4C00h ; function: exit program and return to DOS int 21h _TEXT ENDS END Start
download this file
But where is the stack in here? By default, SP will be equal to FFFE when the program gains control of the CPU and SS will be equal to CS. Therefore, the stack is at the end of the program and will continue to grow toward the program. It is up to the programmer to make sure that the stack does not collide into the program.
To compile and run this program type the following
>tasm hw_com >tlink /t hw_com >hw_com
Now take a look at the size of your final executable... amazing isn't it? Makes you wonder what some programs are doing. Think back to our C or C++ examples.Last Modified: January 26, 1999 - Barry E. Mapen