Comparing “Hello World” with DDT and ASM in CP/M
Introduction
With DDT, one can use the inline assembler to write small programs. CP/M also offers ASM, which is better suited for assembling more advanced programs. In this post, I use both tools to write a small “Hello World” program and compare the two workflows.
Dynamic Debugging Tool
To write a small “Hello World” program using DDT, open up the program and run A100 to start the inline assembler at memory position 0x100.
Type the following assembly instructions:
mvi c,9
lxi d,109
call 5
retAfter writing ret, hit the return key twice to return to the command line of DDT. Next, we run s109 to modify the memory starting at location 0x109. We enter the following values
48
65
6c
6c
6f
20
57
6f
72
6c
64
21
24
00This corresponds to the string “Hello World!$” in ASCII encoding, followed by a zero. The ‘$’ acts as the terminating character, while ‘0x00’ serves as a padding character. Feel free to leave it out; it is not used.
Note
If you would like to run this program from inside DDT, do not forget to change ret to rst 7. Here, we use ret so that the program can be run from the command prompt.
At this point, the program resides in memory. To exit DDT, type g0. We return to the CP/M prompt A>. Here, we type
save 1 hello.comThis saves a single page of memory, 256 bytes, starting at location 0x100 to the file HELLO.COM. We can now execute the program by running hello from the command line, which writes “Hello World!” to the terminal.
ASM
We are going to perform the same task as before, but now using ASM. First, let us clean up the previous HELLO.COM file by running:
era hello.comNext, open the line editor ED. At its command prompt, type I to enter insert mode and write the following assembly code:
ORG 100H
MVI C,9
LXI D,MSG
CALL 5
RET
MSG:
DB 'Hello World!$',0After typing the 0, press CTRL+Z to write the end-of-file marker. At this point you return to the ED command line. Type E to exit and save the file to floppy disk.
Warning
Use single quotation marks around the “Hello World!” string. Double quotation marks will not work.
From the CP/M command prompt, you can run
type hello.asmto see the contents of the file. It should reflect the assembly code typed in via ED. At this point, we are ready to assemble the program. To do so, run:
asm helloWarning
Do not write an extension after “hello” in the command above. In fact, writing asm hello.asm will produce an error message.
The output of the command above should yield
CP/M ASSEMBLER - VER 2.0
0117
000H USE FACTOR
END OF ASSEMBLYThis shows that the final address written to is 0x117. At this point, three files are generated:
HELLO.PRN: A print or listing file containing a human-readable listing of the assembly source code, along with the corresponding machine code and addresses. This file can be printed usingtype hello.prn.HELLO.HEX: An Intel HEX file containing an ASCII-encoded hexadecimal representation of the machine code. This file can be printed usingtype hello.hex.HELLO.OBJ: An object file containing the machine code generated by the assembler. This can be used in the next step to generate an executable.COMfile.
Hint
It is insightful to view the contents of HELLO.PRN and HELLO.HEX using the TYPE command.
Finally, produce a .COM file by running:
load hellowhich will yield the following output
FIRST ADDRESS 0100
LAST ADDRESS 0116
BYTES READ 0017
RECORDS WRITTEN 01At this point, HELLO.COM has been created and can be launched by running hello from the CP/M prompt.
Comparison and conclusion
For quick-and-dirty small assembly programs, I prefer DDT, because the program being written can be tested directly from the DDT environment. The biggest downside of the inline assembler is that it has no support for labels, so one has to do a bit of mental arithmetic to figure out all the addresses.
For larger programs, ASM together with ED is the way to go, although ED is not a particularly friendly editor. In ASM, labels are supported, so part of the address calculation can be delegated to the assembler.