CMSC313, Computer Organization & Assembly Language Programming, Fall 2012

Project 3: Octal Dump

Due: Thursday October 4, 2012, 11:59pm


The objective of this programming project is to have you practice working with subroutines and file handling.


For this project, you will write an assembly language program that produces an "octal dump" of a file. For example, suppose we have file called testfile that contains the single line: don't blink, blink and you're dead (with a line feed at the end), then the output of your program will be: 00000000000 04733467544 00000000004 15430420164 00000000010 05432667151 00000000014 15133061040 00000000020 14110065556 00000000024 17110062156 00000000030 16211672557 00000000034 14531020145 00000000040 00002462141 All the numbers shown are in octal (base 8). The first column of the output is the offset of the bytes in the file. These numbers are simply counting up by 4 in octal. The second number of each line is the value of the 4 successive bytes in the file.

For example, the second number on the first line of the output is the value of the first 4 bytes of the file:

ASCII: d o n ' Octal: 144 157 156 047 binary: 01 100 100 01 101 111 01 101 110 00 100 111 Recall that numbers are stored in "little endian" format, so the 32-bit number represented by these 4 bytes is: binary: 00 100 111 01 101 110 01 101 111 01 100 100 binary: 00 100 111 011 011 100 110 111 101 100 100 octal: 0 4 7 3 3 4 6 7 5 4 4 The second row of binary numbers above is simply the first row regrouped into 3 digits.

Your program must implement two subroutines labeled by Print_Octal and Print_Char. The Print_Octal subroutine must print out the value of the number in the EAX register to STDOUT as an octal (ASCII) string. You must use this subroutine to print out the offset and the 4-byte values. Your Print_Octal subroutine must guarantee that none of the registers are altered after returning. It will accomplish this by saving the registers that it will use on the stack and restoring these registers prior to RET.

Similarly, the Print_Char subroutine prints out a single character stored in the AL register to STDOUT. The Print_Char subroutine must also guarantee that none of the registers are altered by the subroutine. You can use Print_Char to print out the space between the two numbers and the line feed at the end of each line.

Your program should read the input from STDIN. We can use input/output redirection to run your program on a file:

./a.out < testfile

Finally, note that your program should work on binary files as well as text files. So you can use any file on the system for testing. (Small files are recommended.) You can check the output of your program using the od Unix command, as follows:

od -to4 -w4 -v testfile Other than leading zeroes in the offset, the output of your program should be identical to the output of the od command with the flags -to4 -w4 -v.

Implementation Issues:

  1. You should review the instructions: CALL, RET, PUSH and POP.

  2. When you restore the registers at the end of a subroutine, remember to POP the registers in the opposite order that you PUSHed.

  3. Implement your Print_Octal subroutine first, and then TEST IT before doing anything else. You should call the subroutine several times using different values stored in the EAX register. Then use the debugger to confirm that none of the registers have changed value.

  4. In NASM, octal constants can be specified by adding the 0o prefix. (That's the digit 0 followed by the letter o.) For example, 0o1234 is 12348.

  5. For this project, you are allowed to read 4 bytes at a time from STDIN (even though this is horribly inefficient). You may assume that except for the last read, each system call will return with 4 bytes read. You may also assume that the end-of-file has been reached when 0 characters are read by a system call.

  6. The last successful read might return with fewer than 4 characters read. In this case, you should make sure that the most significant bits are padded with 0's.

  7. You may want to reuse your code from Project 2 in your Print_Octal subroutine. This is allowed. However, you must still use the EAX register to hold the value to be printed and your subroutine must not alter the registers. Thus, some modification will be needed.

Addendum: if your Project 2 did not work ...

If your Project 2 does not work or is buggy, you can use pre-compiled code that prints an octal string to stdout. Here's how:

  1. Copy the prtoct.o file to your directory: cp /afs/ . The code in this file will print out the value stored in the EBX register (not EAX) as an octal string (ASCII) to stdout.

  2. In your assembly program, you need these two lines near the beginning of the file: extern prtoct global jump_back_in The first line says the label prtoct is in a separate .o file. The second line says that code in other .o files are allowed to use the label jump_back_in in your own code.

  3. To use the code in prtoct.o, you can simply jump to the label prtoct. When prtoct is done, it will jump to the label jump_back_in. So, you need to have jump_back_in defined in your program. This will probably be right after the jump instruction: jmp prtoct jump_back_in:

  4. You still need to write the assembly code to make a Print_Octal subroutine.

  5. Note: the code in prtoct.o prints out the value in the EBX register, not the EAX register.

  6. The code in prtoct.o uses the EAX, EBX, ECX, EDX and EDI registers.

  7. If you take this option, please make a note in a file named README and submit the file along with your code and typescript file.

  8. NEW: When you use ld to link & load your program, you have to include both .o files: ld octdump.o prtoct.o

Turning in your program

Use the UNIX script command to record some sample runs of your program on several small files. Check your output against the output of the Unix od command.

You should submit two files: 1) your assembly language program and 2) a typescript file of your sample runs. The UNIX command to do this should look something like:

submit cs313 proj3 octdump.asm typescript

Last Modified: 3 Oct 2012 13:05:04 EDT by Richard Chang
to Fall 2012 CMSC 313 Homepage