> ASM TEST the source file TEST.ASM on the current disk is assembled and the output files TEST.HEX and TEST.PRN are written to the current disk in the current user area code. >ASM TEST.ABC the source file A:TEST.ASM is assembled and the output files B:TEST.HEX and C:TEST.PRN are created.There are two disk identifiers that are reserved by the ASM.COM utility the "X" and "Z" disk letters. The "X" disk identifier in the file extension is used to force the listing file to the current console device. The "Z" disk identifier in the file extension is used to suppress the the output of the hex file and the listing file.
> ASM TEST.AAZ the source file A:TEST.ASM is assembled. The hex file A:TEST.HEX is created. The listing file is not output. > ASM TEST.AZX the source file A:TEST.ASM is assembled. The hex format output file is not created. The listing file is output to the current console device.
If an error is detected during the assembly process the ASM.COM utility program will display the current address followed by a single upper case character error code. The error will be display on the current console and listed in the ".PRN" listing file if it is created.
ASM.COM error codes:
- D - The operand is too large to store in the defined space.
- E - A required operand was not provided or operand expression can not be resolved.
- L - Duplicate label or no label allowed in statement.
- N - Unsupported ASM.COM operation.
- O - String too long or expression is to complex to resolve.
- P - Second pass of assembler resolved a different value for a label or expression. Can be caused by duplicate labels or expression values that are not resolved before they are used.
- S - Statement syntax error (ie. EQU with no label or value).
- U - A label in an operand expression has not been defined prior to the current statement.
- V - An operand value is out of range for its defined type.
An assembler source file is composed of assembler text statements. An assembler statement is composed of one to five parts. Each statement part is separated by one or more spaces. The order of an assembler statements parts is fixed. Multiple assembler statements can be included in a single text line. Each assembler statement is separated by an exclamation mark character. Sequence Label Operation Operand ;Comment Sequence is a string of decimal characters terminated by one or more space characters.
The assembler does not check for a valid number in this field. Label is a string of letters and decimal characters starting with a letter that is used as to represent the address of a statement or the assignment of a value. The dollar sign character can be used to separate a label string into more readable parts and will be ignored by the assembler. The first sixteen characters of a label are used the remaining characters are ignored. Mnemonic names and assembler directives are reserved and may not be used as labels. Operation a CPU mnemonic (OR, AND, DEC...) or an assembler directive (EQU, DS, DB...). Operand an assembler expression or a numeric value. In the case of the "DB" assembler directive can be a string of characters. A numeric value can be represented in Binary, Hexadecimal, Octal or Decimal by appending a character to the numeric string to define the values radix . By default as values default to decimal. Appending the appropriate character (B, H, O) to the value changes the radix for that value. Operand expressions evaluate to an unsigned sixteen bit number. Comment any string of printable characters except an exclamation mark character. A comment always starts with a semicolon character.
The following table lists the ASM.COM assembler directives:
Directive | Description |
DB operands | The values of the operands are assembled one byte for each comma separated value. An operand that is a character constant may contain up to sixty four characters. Each character will be assigned to the next byte of storage. |
DW operands | The values of the operands are assembled one sixteen bit word for each comma separated value. |
DS operand | The value of the operand is added to the current location counter to reserve space. |
EQU operand | The value of the operand is evaluated and the required statement label is assigned the value of the operand. |
SET operand | The value of the operand is evaluated and the required statement label is assigned the value of the operand. Unlike the "EQU" command the value may be updated in a latter assembler statement. |
ORG operand | Sets the value of the current location counter. The operand's value is used as the next address to write. |
IF operand | If the value of the operand evaluates to zero all statements until the next "ENDIF" directive are ignored. |
ENDIF | The scope of the inner most "IF" directive is ended. |
END {operand} | Indicates the end of the assembler source file. If the optional operand is specified its value is passed to the ".HEX" file as the program start address. |
Each of the 8080 CPU registers has a reserved label that can be used as a statement operand value; A, B, C, D, E. H. L, M, SP and PSW. The "$" can be used to represent the current assembly address in an operand expression. The following table lists supported numeric operators that can be used in statement operand expressions.
Operation | Description |
+Y | The value of Y. |
-Y | The two's complement of the value of Y. |
X+Y | Unsigned sum of X and Y. |
X-Y | Unsigned difference of X and Y. |
X*Y | Unsigned product of X and Y. |
X/Y | Unsigned division of X and Y. |
X MOD Y | Remainder of X/Y. |
NOT Y | one's complement of Y. |
X AND Y | Logical and of X and Y. |
X OR Y | Logical or of X and Y. |
X XOR Y | Logical exclusive or of X and Y. |
X SHL Y | Logical shift left of X by Y bits. |
X SHR Y | Logical shift right of X by Y bits. |
Assembler statement operand expression may use parentheses to order compound expression evaluation. The code sample below is an example of assembler code that implements the "Hello World" program.
;This is an example of the "Hello World" program.
;Uses 8080 assembler mnemonics.
ORG 100h ;cpm programs start address.
JMP START ;go to program start.
;Variable storage space
MsgStr: DB 13,10,'Hello world.',13,10,0
Stack1: DW 0 ;place to save old stack.
Sbot: DS 32 ;temp stack for us to use.
;Constants
STOP: EQU $-1 ;top of our stack.
BDOS: EQU 5 ;address of BDOS entry.
;Start of code segment
START: LXI H, 0 ;HL = 0.
DAD SP ;HL = SP.
SHLD Stack1 ;save original stack.
LXI H, STOP ;HL = address of new stack.
SPHL ;stack pointer = our stack.
LXI H, MsgStr ;HL = address of string.
LOOP1: MOV A, M ;read string char.
ORA A ;set cpu flags.
JZ EXIT ;if char = 0 done.
MOV E, A ;E = char to send.
MVI C, 2 ;we want BDOS func 2.
PUSH H ;save HL register.
CALL BDOS ;call BDOS function.
POP H ;restore HL register
INX H ;point to next char.
JMP LOOP1 ;do next char.
;Exit and return code
EXIT: LHLD Stack1 ;HL = entry stack address.
SPHL ;SP = value on entry.
RET ;return control back to CPM.
END
The image below shows a CPM session that first compiles the file "HELLO.ASM" into the files; "HELLO.HEX" and "HELLO.PRN". The LOAD.COM utility program loads the "HELLO.HEX" file into memory then saves a binary image to the file "HELLO.COM". Finally the HELLO.COM program is run.