1. 'null' Program

Home Up Next

Well, first things first, I suppose. Let's just create a short program that doesn't do anything, but runs successfully. We can try this in several different ways, too. You can choose which way works better for you or else try all the methods just to get familiar with them.

It's sometimes not entirely clear from simple text examples, if you are new to these tools, the exact part you type. So, in the following examples, I'll underline and color-code those parts which you type. I'll also use a special symbol, «, when you are supposed to use the ENTER (or carriage return) key. Hopefully, that will help clarify the details a bit.

Using DEBUG

Let's try building this first program using the widely available DOS DEBUG.EXE debugger program.

Under DEBUG.EXE, it goes something like this:

C>debug «
-a «
102D:0100 mov ah, 4c «
102D:0102 int 21 «
102D:0104 «
-r cx «
CX 0000
:4 «
-n lesson01.com «
-w «
Writing 00004 bytes
-q «

C>

There's documentation on the DEBUG commands available from the Microsoft web site mentioned on my PC Docs page, for fuller details on those commands. (For convenience, though, here it is: Microsoft's MS-DOS Technical Reference. When you go there, select MS-DOS and then look down the list until you see DEBUG mentioned. Click on that. You should see a list of commands that you can then examine.)

A quick walk-through of the above commands, though: "start DEBUG.EXE; ask it to assemble some code ('a'); enter in a couple of instructions and finally hit ENTER to stop code entry; change register CX so that its value is 4, as the 'w' command used later will use this to decide how many bytes to write to disk; name the file 'lesson01.com'; write the number of bytes in BX:CX (currently 0:4, because I assumed that BX is 0 when I started DEBUG) to 'lesson01.com' starting at the address of CS:0100h, since that is the default starting address to write; quit DEBUG.EXE and go back to DOS."

The result from the above sequence will be a program in your directory called lesson01.com. This is a genuine program that will run and promptly quit back to DOS. Check it out by first listing the directory and finding that file. Next, try and run it by simply entering:

C>lesson01 «

C>

This program is designed to "do nothing." Hopefully, it comes right back to the C-prompt. Yes?

Using GRDB

Let's try building this first program using the web-available GRDB.EXE debugger program, written by David Lindauer. You can get this program from my PC Tools web page. (For convenience, it's at: David Lindauer's Debugger Page.)

Under GRBG.EXE, it would look like:

C>grdb «

Get Real Debugger Version 6.8  Copyright (c) 1997-2004 David Lindauer (LADSoft)
GRDB comes with ABSOLUTELY NO WARRANTY, for details type `?g'
This is free software, and you are welcome to redistribute it
under certain conditions; type `?gr' for details

History enabled
eax:00000000 ebx:00000000 ecx:00000000 edx:00000000 esi:00000000 edi:00000000
ebp:00000000 esp:0000FFEE eip:00000100 flag:00000202 NV UP EI PL NZ NA PO NC
ds:183F es:183F fs:183F gs:183F ss:183F cs:183F
183F:0100 B4 4C          mov          ah,004C

->a «
183F:0100  mov ah, 4c «
183F:0102  int 21 «
183F:0104  «
->w @cs:0100 lesson01.com,4 «
->q «
C>

Again, the result will be a program in your directory called lesson01.com. And again, this is a program that will run and promptly quit back to DOS. Check it out by first listing the directory and finding that file. Next, try and run it by simply entering:

C>lesson01 «

C>

This (same as with DEBUG) program is designed to "do nothing." Hopefully, it comes right back to the C-prompt. Yes?

Using ML

Now, let's try building this same first program using Microsoft's ML.EXE assembler and LINK.EXE linker. You can get these programs from my PC Tools web page.

First, we need to edit in some source code for the assembler to use.

C>copy con: lesson01.asm «
.model tiny «
.code «
.startup «
.exit «
end «
^Z
        1 file(s) copied

C>

That last line you entered is really a control-Z. You just hold the CTRL key down and, simultaneously or just after while still holding CTRL down, type 'z'. This ends your input to the file. At this point, you now have an assembler source code file called lesson01.asm in your current file directory.

Now, to assemble this file:

C>ml /Fl /Sa lesson01.asm «
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000.  All rights reserved.

 Assembling: lesson01.asm

Microsoft (R) Segmented Executable Linker  Version 5.60.339 Dec  5 1994
Copyright (C) Microsoft Corp 1984-1993.  All rights reserved.

Object Modules [.obj]: lesson01.obj /t
Run File [lesson01.com]: "lesson01.com"
List File [nul.map]: NUL
Libraries [.lib]:
Definitions File [nul.def]:

C>

Now, you should also have a few new files in your current file directory, including lesson01.obj and lesson01.com. The file lesson01.com is the same program generated using the other methods. There is also lesson01.lst. But look at that in a moment.

Looking at the above output from the ML command line, you can see that there are actually two programs that ran. The first few lines come from the assembler itself, as it assembles lesson01.asm. The assembler reads lesson01.asm and generates lesson01.obj. But then another program title appears mentioning the segmented executable linker. That's the linker program, which takes the file lesson01.obj and generates lesson01.com, the final program file we wanted. You'll need both programs to make this work as shown above.

A quick description of the source code in lesson01.asm, in order of the lines we typed in above, is: tell the assembler that we want to build a .COM type program (TINY); tell the assembler we want to start writing code; tell the assembler to start at the beginning of the code where DOS will start this program; tell the assembler we want to exit to DOS (this special directive in the assembler is what actually generates the same two instructions we used when using DEBUG and GRBD); tell the assembler we are at the end of the source code file.  That's it!

In the above code we just assembled, there is a statement called ".EXIT" This is what generated the same code we also made with DEBUG, for example. If you type out lesson01.lst you will see those two instructions in the listing.

What Does It All Mean?

In the first wo examples shown here, we entered two instructions. The first instruction set a specific number into the AH register of the CPU. The second instruction performed a special kind of function call, called an INT instruction. It turns out that when DOS is running on your machine, it automatically intercepts all INT 21H type function calls and looks at the AH register to see what you wanted it to do. If you look up Function 4C in the technical reference for DOS programmers mentioned at the top of my PC Docs web page, you will find the following description there:

4CH -- Terminate a Process (EXIT)

Purpose
        Terminates the current process and transfers control to the invoking
        process.

Examples

            MOV AH,4CH         ; Function Call -- Terminate a Process
            MOV AL,ErrorCode   ; Set ERRORLEVEL
            INT 21H            ; Issue request to DOS
            INT 20H            ; Be safe if running on PC/DOS 1.1
        ----
        ErrorCode DB ?         ; Error Code (sets ERRORLEVEL if EXEC¢ ed
                               ; by COMMAND.COM)

Comments

        In addition, a return code can be sent. The return code can be
        interrogated by the batch subcommands IF and ERRORLEVEL and by the
        wait function call 4DH. All files opened by this process are closed.

If you read this closely, you'll see that we didn't set register AL to anything. Since ERRORLEVEL isn't used that often, it's value isn't important for our first program. That's why I didn't set it.

In the case of the assembly code for ML, we used a .EXIT directive which tells the assembler to generate the same MOV and INT instructions. If we wanted to set register AL, as well, we could have told the assembler something like ".EXIT 0" to set the exit value. The assembler would have then generated slightly different code so that the AL register was set to 0, in this case.

I hope you had good luck getting all this to work out on your first program!

 

Last updated: Wednesday, July 07, 2004 11:42