Computer Engineering II
Machine Problem 0

Schedule Lab schedule
Homework Lab Manual
Machine Problems Resources
Final Project Photos
Gradebook Feedback
Syllabus Archives
Lectures Download NASM
Home Restricted access
Assigned Thursday, 24 August 2005
Due Date Friday, 2 September 2005, 5:00 P.M.
Purpose Introduction to NASM and Turbo Debugger
Points 10

Introduction

This machine problem will introduce you to the computers, network, and software in the ECE 390 laboratory. For this machine problem, you will learn how to edit, assemble, debug, and execute an existing, simple assembly language program. A full listing of the program and a Makefile are given at the end of this assignment. Electronic copies of the program are available in the lab or on-line as mp0.zip.

Preliminary Procedure

  1. Read Chapters 1 (Introduction to the Course) and 2 (Using the PC) of the Lab Notes.

  2. Visit the ECE 390 laboratory in Room 238 Everitt Lab. You will need an activated key card to open the door.

  3. Have a seat at any available computer in the laboratory. The machine should boot into Windows (if not already on).

  4. Enter your login and password. Change your NT login password at http://accounts.ad.uiuc.edu/.

  5. Start a DOS shell by double clicking on the Command Prompt icon on the desktop. (If Command Prompt is not on the desktop, go to start > All Programs > Accessories to find Command Prompt.) You can choose a larger font size by right-clicking on the title bar at the top of the window, choosing Properties, and clicking on the Font tab.

  6. For the machines in the ECE 390 lab, you will be using the following drive letters:

    Drive Description Purpose
    C: Hard Drive (local) Holds Windows, NASM, and other applications
    Do not store files here!
    V:\ece390\ Class Drive (network) Class material, libraries, examples code
    (Read Only)
    W: Your personal home directory (network) This drive will be mounted each time you log in,
    and is accessible from any machine in the lab.
    (Store your MPs here!)

  7. Copy the MP0 directory on the class drive to your private directory by typing:
    xcopy /s V:\ece390\mp0 W:\mp0
    When prompted, respond with D to copy the entire directory.

  8. Go into your private directory
    • Switch to your drive by typing
      W:
    • Switch to the mp0 directory by typing
      cd \mp0

  9. From the desktop, run Windows Explorer. Navigate to your W: drive, open the mp0 folder

  10. Double-click on the mp0.asm file to edit the program. (If you are working at home, you'll need to install your own text editor. Avoid Notepad and QuickEdit.). Scroll through the program, but don't make any changes yet.

    The code is broken into several sections to illustrate the various components in an assembly program. This is certainly not the only way to organize an assembly program, but it gives a good starting point. Again, you do not need to understand precisely what the statements are doing at this point, but notice the overall structure of the program. This will be a good reference for future machine problems.

    • Section 1 defines several constants to be used throughout the program. Each constant has a value that is associated with a particular name using the EQU statement.
    • Section 2 declares external procedures (meaning code that has already been written but is in a different file) that will be used in this program. External procedures are declared with the EXTERN statement.
    • Section 3 defines a special required structure called a stack segment. You will discover why a stack is necessary in the future. The stack segment is declared using the SEGMENT stkseg STACK statement.
    • Section 4 declares the beginning of the code segment - that part of the file which contains the program instructions. The code segment is declared using the SEGMENT code statement.
    • Section 5 initializes several variables to be used. For this program, these variables are just sequences of characters called strings. Variables can be defined using the DB statement. It is important that variables are not defined in a part of your program that is executed.
    • Section 6 contains the code for the program initialization: setting up segment registers for the default and stack segments. Program execution begins at the ..start: label. The program execution goes immediately into the MAIN procedure (next section) after completing this section.
    • Section 7 contains the code for the main procedure.

  11. From the DOS window, assemble and link MP0 by typing make. This command will read Makefile and invoke the following commands:
    nasm -g -f obj -o mp0.obj mp0.asm -l mp0.lst
    tlink /c /v mp0.obj, mp0.exe, mp0.map, lib291.lib
    At this point, you should have just created the executable program called MP0.EXE.

  12. Run the program by just typing its name, MP0
    Try giving the program different input. Remember: this program is looking for upper-case letters!

  13. Now examine your program by running the debugging tool Turbo Debugger (TD).
    TD MP0
    Turbo Debugger will read your MP0.EXE program and allow you to step and trace through the program as it executes.

    • If the Regs window is not already open, open it. From TD's View pulldown menu, select the options to view Registers. Resize and adjust the locations of the windows on the screen as necessary.

    • Press the function key F8 to execute the first instruction of your program. Notice that register AX has changed value. The first instruction of the program (MOV AX, CS) puts the value of CS into AX. Also notice that register IP, the instruction pointer, has changed value. It always specifies the offset of the next instruction to be executed. The instruction displayed is the next one to be executed.

    • Press F8 again to execute the second line of code. Notice that the DS register changes.

    • If the Dump window is not already open, open it. From TD's View pulldown menu, select the options to view Dump. Memory addresses are shown on the left in segment:offset format. Check that the memory segment is DS. If not, you can right click in the Dump window and click on Goto.... Type ds:0 and press Enter to display the start of the data segment. Each data byte appears in hexadecimal. On the far right side of the screen are the characters whose ASCII codes are given by the bytes. The ASCII contents of the memory should look familiar.

    • Press F8 a few more times to step through your code. Stop stepping when you reach the input prompt.

    • From the program's grade prompt, select a letter grade. Use F8 to step through the rest of the program. You toggle between the debugger screen and program output by pressing Alt-F5.

    • Once the program has terminated; Select Program reset from TD's Run menu. Run the program again a few times with different input until you understand how the program is executing.

    • Navigate to the View menu, and select CPU. Resize and adjust the locations of the windows on the screen as necessary.

    • Again select Program reset from TD's Run menu. Right click in the code area of the CPU window, and click on the Mixed option until it reads No. Click outside the popup menu to make it disappear. Now, In TD's CPU window, you will see the machine code for the same program. In first column, you will see where each line of code is located in memory (in segment:offset format). In the second column, you will see the program bytes in hex. In the third column, you will see the human-readable opcodes of the program. Notice that text labels have been replaced with numeric values (pointers and constants) by the assembler and linker.

    • Again select Program reset from TD's Run menu. Run the program again a few more times with different input.

    • To speed up the debugging process, TD allows the programmer to execute large sections of code between break-points. Click on the line at offset=00FB and press F2 to set a breakpoint in your program at the first compare statement.

    • Restart your program, then press F9 to run through your code until the breakpoint.

    • When prompted for a grade, enter B. The screen should return to the debugger at your breakpoint.

    • Record the value in register AL.
      AL = ____

    • In the Dump window, change the value of the byte at (data segment) offset=0 to 44 (hex). Continue running the program until it terminates. Notice that the output message is grossly incorrect.

    • In the space below, explain what the program is doing.

    • From TD's File menu, choose Quit to return to the DOS prompt.

  14. Now return to your text editor to modify MP0.ASM. You need to make the following changes:

    1. Put your name and the current date at the beginning of the program
    2. Add a feature to the program that prints a message of your choice when the grade C is selected.
    3. Assemble and test your program with all possible inputs. Debug with TD as necessary until the program works as expected.

  15. Now return to your text editor and add a line to MP0.ASM.

    1. Add a new variable to your program called mystery that is initialized with the hex values of 0FEh,0C0h. (This is NASM's method of entering hex values.) Declare this variable at the location in your code immediately after the input is read using the lib291 kbdine function.
    2. Re-Assemble your code and run TD.
    3. Run your program a few more times and observe what happens. Try switching between the Module (source) window and CPU (disassembly) windows.
    4. Browse the CPU window record what addresses the mystery bytes were stored in.
      Address= ______ : ______
    5. In the space below, explain how the program behaves differently and why.
    6. Finally, Move this variable declaration to where it belongs in the code.

    Final Steps

    1. Demonstrate your updated MP0.EXE to a TA or to the instructor. Review your solutions to the question with the TA. Be prepared to be quizzed by the TA with additional questions about your TD debugging experiences. The TA will not allow you to submit your MP until he or she is satisfied that you have mastered TD.

    2. Have the TA handin your MP online.

    3. In the DOS window, type exit to close the window.

    4. Log off by clicking on the Start button and selecting Log off. (Do not shut down the computer.)

    5. You are now finished!

    mp0.asm

    ; MP0 - Your Name - Today's Date ; ; This program illustrates a (very) basic assembly program and ; the use of LIB291 input and output routines. ; By working on this code, you will have the opportunity to ; exercise the tools for this class, namely the editor, ; the Assembler (NASM), and the debugger (TD). ; Be sure to put your name in the places where it says 'Your Name' ; and also change the date where it says 'Today's Date'. ; The changes that you need to make to this program are ; described in the MP0 assignment page. BITS 16 ;====== SECTION 1: Define constants ======================================= CR EQU 0Dh LF EQU 0Ah BEL EQU 07h ;====== SECTION 2: Declare external procedures ============================ EXTERN kbdine, dspout, dspmsg, dosxit ;====== SECTION 3: Define stack segment =================================== SEGMENT stkseg STACK ; *** STACK SEGMENT *** resb 64*8 stacktop: ;====== SECTION 4: Define code segment ==================================== SEGMENT code ; *** CODE SEGMENT *** ;====== SECTION 5: Declare variables for main procedure =================== mygrade db 0 question db 'What grade would you like in ECE390? ','$' Exitmsg db CR,LF,'Good Luck!',CR,LF,'$' invalid db CR,LF,'Not a valid choice! ',CR,LF,'$' Amsg db CR,LF,'Learn all material and Submit MPs early.',CR,LF,'$' Bmsg db CR,LF,'Keep up in class and submit MPs on time.',CR,LF,'$' Dmsg db CR,LF,'Skip a few machine problems.',CR,LF,'$' Fmsg db CR,LF,'Sleep through exams.',CR,LF,'$' ;====== SECTION 6: Program initialization ================================= ..start: mov ax, cs ; Initialize Default Segment register mov ds, ax mov ax, stkseg ; Initialize Stack Segment register mov ss, ax mov sp, stacktop ; Initialize Stack Pointer register ;====== SECTION 7: Main procedure ========================================= MAIN: mov dx, question ; Prompt user with the grade question call dspmsg call kbdine mov [mygrade],AL ; Save result .CheckGrade: cmp byte [mygrade], 'A' ; Check if A student jne .NotGradeA mov dx, Amsg ; Print message for A students call dspmsg jmp .mpExit .NotGradeA: cmp byte [mygrade], 'B' ; Check if B student jne .NotGradeB mov dx, Bmsg ; Print message for B students call dspmsg jmp .mpExit .NotGradeB: cmp byte [mygrade], 'D' ; Check if D student jne .NotGradeD mov dx, Dmsg ; Print message for D students call dspmsg jmp .mpExit .NotGradeD: cmp byte [mygrade], 'F' ; Check if F student jne .NotGradeF mov dx, Fmsg ; Print message for F students call dspmsg jmp .mpExit .NotGradeF: mov dl, BEL ; Ring the bell if other character call dspout mov dx, invalid ; Print invalid message call dspmsg jmp .FinalExit .mpExit: mov dx, Exitmsg ; Type out exit message call dspmsg .FinalExit: call dosxit ; Exit to DOS

    Makefile

    MPNAME=mp0 all: $(MPNAME).exe clean: rm -f $(MPNAME).obj $(MPNAME).exe $(MPNAME).lst $(MPNAME).map %.exe: %.obj tlink /c /v $<, $*.exe, $*.map, lib291.lib %.obj: %.asm nasm -g -f obj -o $*.obj $< -l $*.lst
    Return to ECE390 Home Page Fall 2005