Course Number: Computer Science
51A
Course Name: Assembly Language
Programming (3 units)
Prerequisite: CSCI 15B (Programming
and Algorithms II) or other introductory high level language course (Class
programs will require the use of C or C++.)
Dates and Times: June 2-July 10, Mon/Tue/Wed/Thu, 9:00a-10:55a (Pacific)
Instructor: John Zenor
Office Phone: 916-898-4414
Message Phone: 916-898-6442
Fax Phone: 916-898-5995
WWW Homepage: http://www.ecst.csuchico.edu/~zenor
E-mail Address: zenor@ecst.csuchico.edu
Textbook: The Revolutionary Guide to Assembly Language, by Vitaly Maljugin, et al, Wrox Press, Birmingham, UK, 1993. (Required)
ISBN 1874416125
Software/Hardware: Microsoft
MASM Assembler (Available in an educational version; see Book Order Form).
Access is required to a PC compatible. MASM will run in a DOS, Windows 3.1,
Windows 95, or Windows NT environment. C or C++ should be available on the
PC. (Borland TASM may be used.) (Required)
Course Description: Today,
assembly language is used when very low level control of computer hardware
is required, or in small sections of software that require the utmost in
performance. The knowledge of assembly language will increase your understanding
of the architecture of computer systems and of how computers function. The
emphasis of this course will be to increase the understanding of computer
systems and the interactions between computer programs and the hardware
of the machine, rather than on developing the skill to author large assembly
language programs. Programming of I/O devices, interrupts, and interfacing
assembly routines to high order languages will be covered.
Topics:
1. Basic computer system architecture
a. Components of microprocessor systems
b. Programmers model of 80xxx microprocessors
c. Machine representation of instructions and data
2. MASM tools and environment
3. Assembly Language Programming
a. Review of number systems
b. Instruction set of 80xxx microprocessors
c. Stacks and interfacing assembly of high order languages
4. Assembly and linking process
a. What the assembler and linker do
5. Low level I/O and interrupts
6. DOS and BIOS services
a. Keyboard
b. Video
c. Disk
Laboratory Projects: Six or
seven small assembly routines will be written that will demonstrate the
concepts of assembly language and I/O. Several of these programs will be
used as components of the final program, which will have an interface to
a C or C++ main program.
Evaluation Procedures:
Programs 55%
Midterm 20%
Final 25%
Installing MASM The instructions for installing MASM are found in the Getting Started manual that comes with Microsoft MASM. This manual contains so much good technical material that it is difficult to find the steps required for installation. The steps for installing MASM on a Windows 95 system are outlined below. Page numbers give the location of related material in the Getting Started manual.
- Navigate (using My Computer) to the A drive and run the SETUP program on Disk #1
- Select the installation using default options using the up/down arrow keys and press enter.
- After reading in all of the disks, a new folder has been created on the C drive named MASM611. Navigate to this folder and open the folder named BINR (or BIN if BINR hasn't been created.)
- The SETUP program does not automatically change any of the configuration files on your computer. Instead, it analyzes your system and puts suggested changes in files in the BIN or BINR folder. Whichever folder has the file NEW-CONF.SYS, I will refer to it as the BIN folder in the following directions.
- The changes to CONFIG.SYS are found in the file NEW-CONF.SYS which is in the BIN or BINR folder. The lines in NEW-CONF.SYS need to be copied into your existing CONFIG.SYS system file. Double clicking on these files can cause trouble, so run NOTEPAD from the START button. Use the open command in the file menu to navigate to the BIN open NEW-CONF.SYS. Be sure and select the see all files option when trying to locate this file.
- Next, open the system's CONFIG.SYS file in a NEW copy of NOTEPAD. Sometimes, the system's CONFIG.SYS folder is hidden, so it may be opened as follows. Use the FIND command under the START button to find all files with names CONFIG.SYS. (Be sure to start the search from C:\) Find the entry in the list of found files that is located in C:\, and click on the icon once with the right mouse button. Then, click with the left button on open with... and choose NOTEPAD.
- Copy the lines from the file NEW-CONF.SYS to the end of the system's CONFIG.SYS file. Delete any of the new lines that duplicate lines already found in the CONFIG.SYS file. If you already have a DEVICE statement for a mouse driver, try your system with the old driver and remark out the new DEVICE statement by putting REM at the beginning of the statement. If the mouse doesn't work, then you can remark out your original DEVICE statement and try the new driver.
- This process needs to be repeated to update the system file C:\AUTOEXEC.BAT by adding the lines from C:\MASM611\BIN\NEW-VARS.BAT (see page 20).
- Repeat the process once more to update the system file C:\WINDOWS\SYSTEM.INI with the lines from C:\MASM\BIN\NEW-SYS.INI (see page 24). This time, don't place the lines at the end of the file, but instead, place them at the end of the [386enh] section. It is possible that the NEW-SYS.INI file will be missing if there are no lines to add.
- Navigate to the folder C:\MASM611\INIT with the My Computer window, and click once on the file: TOOLS.PRE. Next, click first copy, then paste from the file menu. This will create a copy of the file. Rename this file copy TOOLS.INI.
- Reboot, and you are ready to try MASM and PWB!!
Using PWB The basic steps for creating, building, and debugging an assembly language program "project" are given below. Details may be found in the Tools and Environment manual. The example given at the beginning of that manual is overly complicated, but does illustrate the procedure.
A project is a complete set of files needed to define and build an assembly language program. The source language files for your programs are, of course, part of this project, but also there are listing files, symbol table files for debugging, and files giving directions for building your program.
It is best to create a separate folder to contain the project files for each programming assignment. This folder should be on a floppy disk for the local students who are using the school's computer labs.
- Create a folder on your floppy for your new project. For the first assignment, the folder name could be TryFlags or TryFlagsProject.
- Copy any files that are needed from the disk supplied with the text into your folder.
- Run PWB.EXE by double clicking on the file or its shortcut in the C:\MASM611\BIN folder. The shortcut may be copied and the copy moved to the desktop to make it easier to find the PWB.
- Once the PWB is running (and the colorful DOS window appears), you may create a new project using the project menu. Type the correct path to the new project folder with project name and press the set project template button. Select Runtime support: None, Project Templates: DOS:EXE, OK, OK.
- You don't have any program files to add to the project yet, so click save list when the add file window appears.
- Under the Options menu, select build options. Select Use Debug Options, OK.
- Using the Options menu:language options:MASM, select Set Debug Options. Check the boxes that will create a listing file with source, machine language, and symbol table: Generate Listing File, List Generated Instructions, Include all Source Lines, CodeView Debugger, OK, OK.
- Using the Options menu:link options, select codeview debugger, debug options. Press the additional debug options "button" and select Full map output. This will give you a link map that tells where each program component will be loaded. Select OK, OK.
- Select new under the file menu to get an editor window for your program. Enter the program. Save your program naming it with a .ASM suffix. E.G.:TryFlags.ASM
- Select edit project from the project menu, and add your new assembly program into the project list. Save the list.
- Start the debugger, running your program, by selecting debug from the Run menu. It will ask you to build your project. That is a good idea, select Rebuild All. The Assembler will assemble your code, the linker will be called, and if there are no errors, the debugger window will appear. You can then start debugging.
- If there were any errors, select View Results, then
- next error under the project menu. It will show you the offending line in your source program, and you can correct it here.
- Continue asking to see the next error until you run out of errors.
- Select debug from the project window to have another try.
- Repeat ad-infinitum until you finally get the debugger.
- You may step through your program one line at a time by using F8 and F10, or you may select go (F5) and run it without interruption.
- In order to watch the contents of memory change, you need to select the memory window options in the options menu (of the debugger). Be sure and check the box that requests that the memory window be continually re-evaluated. If you don't check this box, the memory window will continue to reflect memory contents just before your program started running.
- Breakpoints may be inserted at any line of code using the set breakpoint item in the Data menu. If go is selected, the computer will stop on any line encountered with a breakpoint set.
- Selecting source window options from the window menu allows you to have intermingled source lines and object code. This will allow you to compare the instructions that are actually running with the lines of source code that you provided.
- F10 will single step through your code, but will not single step through any called subroutines (It will "step-over" the subroutine call.) The subroutine will be called correctly, it will simply not be debugged. This is handy when you are using a subroutine that has already been debugged, or when a system routine is called.
- F8 will single "step-into" a subroutine that is called, allowing you to debug the subroutine itself.
- You may execute down to a given instruction by right-clicking on the source line, moving the cursor to the source line, and then pressing the F7 key.
- This is all a great bag of fun, and you can twiddle the arrangement and content of all of the sub-windows using the size controls and options provided in the window menu. These settings will be remembered the next time you debug, so it is worth taking the time to set everything up just as you want it.
- A little time and care in programming can save hours of debugging!
- Taking the time to add comments to your code while first entering it will save much time in the long run. It is very hard to figure out what an undocumented assembly language program is doing after even a brief intermission. Comments help you to quickly locate desired sections of code.
- Note: On the machines at the lab, it is frequently necessary to make sure the path is set correctly for the PWB to run. Right mouse-click on the PWB shortcut icon. Select Properties, then select the Program tab. Under Batch file, type: C:\MASM611\BIN\NEW-VARS
Using Visual C++ To create and debug a Visual C++ program, follow these steps. It is a very good environment, but the physical manipulation of frames within the windows can be a bit tricky!
- Find Visual C++: Look for the file Visual C++ within the folder Microsoft Developer Studio and run Visual C++
- Create a new project. Don't forget to navigate to a disk drive for which you have write priviledges. Select New from the File menu.
- Be sure and select Win32 Console Application
- Enter a name for your project (no extension is needed).
- Create a new file for your main program using New in the File menu.
- Enter your main program text. Don't forget to put any prototypes needed for external functions at the top, along with any necessary #includes. If you use void main, don't return anything!
- If you are using Visual C++ Version 4, be sure and put an extra cin statement at the end of your program to make execution pause long enough to be able to look at your results. When you enter this last input value, the program will exit. This does not seem to be necessary on Version 5.
- Select Rebuld All from the project menu.
- To see details about your errors, double click on the error line in the bottom window.
- Correct your errors, then recycle through this step.
- It is not necessary to save your file after correcting it, that will be done automatically
- To run your program without the debugger, select !Execute xxx.exe from the Build menu, or press Ctrl+F5
- To run your program with the debugger, select Start Debug:Step Into from the Build menu. A small Debug window will pop up. Hold the mouse over these buttons to get a message about what they will do.
- F10 will step-over. Use this for normal debugging since you do not want to step into the C++ library code!
- F8 will step-into. Use this if you want to "step-into" one of your own functions. F10 will skip debugging of any functions invoked as you are debugging, F8 will debug them.
- Ctrl+F10 will run without debugging up to the cursor position in the source code.
- The icon in the far right of the debug window (with the little magnifying glass) will dissassemble your C++ program and show you the assembly language generated for each line of your program.
- While debugging, you cant see the console window with your printed output, nor can you see the prompts for input. To switch to the console window, use Alt-tab. Look at your output, type any needed input, and then switch back to your C++ windows with Alt-tab.
- To generate a full assembly language file for your C++ program:
- Select Settings under the Project menu, then select the C/C++ tab.
- In the Category field, select Listing Files.
- In the Listing file types field, select Assembly with Source Code.
- Rebuild your project, open file xxx.asm to see the assembly program. This file will be inside your Debug folder. You have to select All Files in the open browser in order to see these files.
Lab Assignment #1 Enter the two programs from Chapter 2 into two different folders on your floppy. Construct one project for each program that will build the program.
Run the flags program one step at a time, annotating a listing of the program with the flag values for OF, CF, ZF, SF after each instruction.
Run the factorials program by placing a breakpoint at the end of the loop so that every time you depress go it will execute one more loop. Single step through one loop. Note that you will want to step over the subroutine call to the input routine. Then execute the remaining loop iterations using the go with the breakpoint. Record the value of the variables on each iteration using an input of 5. Only record the variables that really change on each iteration. Execute to the end of the program.
Submit assembly listings, and linker maps for each program, along with the annotated data collected in any reasonable format of your choice. Label and describe the output well enough that it is possible to interpret.
This assignment is due Monday, 9 June. Late points will not be subtracted until Wednesday. 10% of the total points will be subtracted Wednesday, and 10% for every day thereafter.
Lab Assignment #2
Memory Dump, Part AThe objective of the next several exercises is to construct an assembly language program that will produce a memory dump of specified memory locations resembling the memory window in the PWB (or the memory dump produced by the DOS DEBUG command). This series of lab assignments will implement this program incrementally, each lab will build on the design and code of the previous lab.
Part A of this lab is to produce a buffer of 80 ASCII characters which will contain the image of one line of a memory dump. The program is to read in a starting address for the dump. It will then construct the buffer containing the following:
<starting address> <byte 1> <byte 2> .... <byte 16> "<16 ASCII characters>"
The characters stored for the <starting address> and <byte 1>...<byte 16> should represent the HEX values. For example, if a byte contains 0A6H, the characters 'A' and '6' should be stored in the buffer.
The portion containing the <16 ASCII characters> should contain 16 bytes, each with the original HEX contents of <byte 1> through <byte 16>. If the original HEX contents of <byte n> represent the ASCII code for a non-printable character, replace that byte with the ASCII code for a period.
Input: For this lab, the input may be in any reasonable format. In future labs, the input will be in HEX.
Output: The fields of the output buffer should be separated by one or more spaces, to produce a pleasing appearance if the buffer were to be printed. A screen dump of the debugger Memory window should be submitted to demonstrate that the buffer has been correctly constructed. The output buffer should contain exactly 80 characters.
To submit display output, produce a screen dump, paste the dump into an editor page, and print the result.
Optional: Print (or display) the buffer. It is interesting to write a C++ program that constructs and prints such a buffer. A pointer to type byte, or char, could be used to contain an address in memory.
Work to be submitted: Assembly and Map listings, screen dumps demonstrating that the program runs correctly.
Program Style: Assembly programs should be self-documenting. The code should be divided into groups of lines that carry out a single function, with a full-line comment explaining the function. Nearly every line should have an explanatory comment. Do not simply parrot the function of the instruction in the comment.
Inputs, outputs, and the function of each program and subprogram should be explained. It is particularly useful to explain register usage in the comments. For instance, if CX is being used as a loop counter, reference the functional name "loop counter" in your comments, rather than "CX".
NOTE: Don't forget to put your name and the assignment name at the top of your listing, followed by an explanation of the assignment. Write the date and time of submission, by hand, on the assignment.
Lab Assignment #3
Memory Dump, Part BDescription: Write an Intel 16-bit assembly language program to produce ASCII and Hex memory dumps of specified memory locations. The starting address and ending address are to be read in from the keyboard in the form <ssss:oooo> (hex). The dump is to be printed on the console device, in the format described for lab assignment #2. This program will demonstrate the use of internal subroutines.
Input Subroutine: The code that reads input from the console in the form <ssss:oooo> is to be made into a subroutine which will be called twice, once for the starting address, once for the ending address. It should be considered and error if the starting and ending address do not both have the same segment address, or if the starting location is after the ending location. Any errors detected on input should be returned to the main program for processing.
Output Buffer Subroutine: The program shall include a subroutine whose purpose is to form a buffer containing the characters for one line of dump output. Input arguments should include the desired buffer address, and the address in memory from which to start this line of the dump.
Main Program: The main program should:
- Call the input subroutine to read in the starting and ending locations for the dump
- Call the output buffer subroutine to form one line of output
- Print the line
- Repeat steps 2 and 3 until the dump is complete
Work to be submitted: Assembly and Map listings, screen dumps demonstrating that the program runs correctly. Provide good self documenting code, in the style suggested for assignment #2. Each subroutine should have a "header" block of comments that fully explains the purpose of the subroutine and its inputs and outputs. Don't forget to write your name and the date and time that this assignment was submitted on the front page.
Lab Assignment #4
External Subroutines and MacrosDescription: Convert the subroutines in lab assignment #3 into externally compiled subroutines. Make macros suitable for calling these subroutines. (This is very simple, do not make it complicated!) Modify the main program from lab assignment #3 to use the macros and external subroutines. The macro definition may be included as part of your main program, or may be included from another file.
Input and Output: Identical to lab assignment #3.
Work to be submitted: Assembly and Map listings, screen dumps demonstrating that the program runs correctly. Provide good self documenting code, in the style suggested for assignment #2. Each subroutine should have a "header" block of comments that fully explains the purpose of the subroutine and its inputs and outputs. Don't forget to write your name and the date and time that this assignment was submitted on the front page.
Lab Assignment #5
Floppy Disk I/ODescription: Write a program to dump a specified sector from a floppy disk. Use this program to dump the contents of the FAT and the directory of a floppy. This floppy should be freshly formatted, with only a few files. Copy Command.com to the floppy as one of the files so that one of the files will be fairly long.
Read the specified sector sfrom the floppy into a buffer that is declared in the main program. Use the dump subroutine from lab assignment #4 to construct the dump of the contents of this buffer.
Input: Read the starting track, sector, side (in hex), and number of sectors to be dumped (hex) from the keyboard. You may use any format that you choose for input, but prompt for each input. For example, print "starting sector: ", and then pause for input. Each input value should be checked to see if it is within a proper range for the type of floppy being dumped before the program proceeds. If any input quantity is not within range, an error message should be printed and the user should be given another chance to type in the value.
Output: Display the dump of the requested sectors using the format of the previous dump assignments. For the address, show the relative address within the buffer. One way to do this is to allign the buffer on a paragraph boundary, and use the <ssss> portion of the address to point to the beginning of the buffer.
Work to be submitted: Assembly and Map listings, screen dumps demonstrating that the program runs correctly. Use sample test cases that demonstrate the correct operation of the program, including its ability to detect the requested input errors. Include a listing of the contents of the FAT and the directory for your floppy, and the actual file contents for a simple, short, text file.
Provide good self documenting code, in the style suggested for assignment #2. Each subroutine should have a "header" block of comments that fully explains the purpose of the subroutine and its inputs and outputs. Don't forget to write your name and the date and time that this assignment was submitted on the front page.
Lab Assignment #6
Interfacing to C++Description: Write a program of your choice that contains a C++ main program and an assembly language subroutine (function). It is preferable for the subroutine/main program to be written in 32-bit protected mode with a FLAT memory model.
Work to be submitted: Assembly listings for the subprogram, C++ listing for the main program, output or screen dumps that demonstrate correct operation of the programs.
Example of a possible project: Write a C++ main program that calls a function to copy a C string from one string variable to another. Write an efficient Assembly Language subprogram that performs the copy.
Suggested approach: First write the main program and the subprogram in C++, print out an assembly source listing of both using the C++ compiler . Observe how the subprogram compiled by C++ handles the arguments, and where they are located on the stack. Name your subprogram with the same name given by C++ to its subprogram (as found in the Assembly source listing). Now, simply remove the "innards" from the C++ generated code and substitute your own code. You may eliminate any of the conditional code generated by the C++ compiler that does not really get compiled.
Create a new MASM project containing only your subprogram. Assemble your Assembly routine using MASM, then add the object (relocatable) file generated by MASM as a file in your C++ project. Since this file is just a subprogram, it doesn't make since to ask MASM to build a program for you, as there is no main program. Just ask it to assemble your code, not to build the project. Don't forget the .386P and .model flat commands in your assembly code! You will not be able to use the MASM debugger on the 32 bit code, so you just have to be VERY careful.
Desperation alternative: For partial credit on this assignment, write the program and the subprogram in C++, get an assembly source/C++ listing, and annotate the listing to explain what the assembly language is doing, and how it works.
Sample Assembly Language Tests and Homework Assignments Homework 1: Intel Addressing Modes
Homework2: Stack Frames
Homework3: Instruction Format
Sample Mid Term #1: Addressing Modes, Number Systems, Flags
Sample Mid Term #2: Instruction Representation, Logical Instructions