EXE program can have any size whereas COM program can have maximally 64kB (just one segment).
At the beginning of program there is program segment prefix (PSP). Because COM program is stored only in one segment so PSP occupies first 256 bytes (100h). Therefore start point begins at 100h. Values of segment registers are set to the begin of segment and don’t change during executing.
COM program in memory:
+-----------------+
| Free memory | SP
+-----------------+ <------------ ^
| Stack memory | |
+-----------------+ |
| Program code | |
| | | 64kB max.
| | IP (100h) |
+-----------------+ <------------ |
| PSP (256 B) | CS,DS,SS,ES |
+-----------------+ <------------ v
| Occupied memory |
+-----------------+
COM example 1:
Data are in data segment and cannot exceed 100h. Binary has 27 bytes.
;tmp_com1.asm
;
;how to compile:
;tasm tmp_com1
;tlink tmp_com1 /t
.model tiny
.data
;text for print
text db 'Hello World!',13,10,'$'
.code
org 100h
start:
;print hello
mov dx,offset text
mov ah,09h
int 21h
;return control back to dos
mov ah,4ch ;dos terminate program
mov al,00h ;return code will be 0
int 21h
end start
COM example 2:
Data are in code segment. Binary has 30 bytes.
;tmp_com2.asm
;
;how to compile:
;tasm tmp_com2
;tlink tmp_com2 /t
.model tiny
.code
org 100h
start:
jmp nav
;text for print
text db 'Hello World!',13,10,'$'
nav:
;print hello
mov dx,offset text
mov ah,09h
int 21h
;return control back to dos
mov ah,4ch ;dos terminate program
mov al,00h ;return code will be 0
int 21h
end start
For more information about COM see wikipedia.
The main problem about creating EXE programs is assignation of correct values to segment registers CS,DS,SS,ES and to stack pointer SP. Similary to COM programs also in case of EXE programs system creates PSP and program is loaded just after PSP.
It is appropriate to define stack .stack 100h
. This definition assures automatic setting of SP register at the top of stack.
In many cases it is also appropriate to segregate code segment .code
and data segment .data
. Definition of data segment itself does not affect setting of segment registers DS,ES. It is neccesary set them manually. After program loading registers will have following setting.
SP
+-----------------+ <------------
| Stack memory | SS
+-----------------+ <------------
| Data |
+-----------------+
| Program | CS
+-----------------+ <------------
| PSP (256 B) | DS,ES
+-----------------+ <------------
It is obvious that DS register is not pointing to data segment. It is necessary do it manually
mov ax,@data
mov ds,ax
EXE Program example:
Binary has 545 bytes.
;tmp_exe.asm
;
;how to compile:
;tasm tmp_exe
;tlink tmp_exe
.model small
.stack 100h
.data
;text for print
text db 'Hello World!',13,10,'$'
.code
start:
;set DS to point to the data
mov ax,@data
mov ds,ax
;print hello
mov dx,offset text
mov ah,09h
int 21h
;return control back to dos
mov ah,4ch ;dos terminate program
mov al,00h ;return code will be 0
int 21h
end start