CS 211: Assignment 3
Why you need this stuff

Back to course page
Sample solution: assign3.c and assign3lib.S

Introduction

Seldom does anybody code an entire program in assembly any more. While it’s still possible to do so, the majority of a program is typically written in a high-level language such as C, C++, or Java, and only the parts that require high speed or low code size are written in assembly language.

For this assignment, you’ll need to write a simple C program and a few simple assembly-language functions, then combine the two into a single executable file. This requires you to understand how functions are called, and requires you to have at least some vague understanding of the linking process.

You’ll need to work on Intel Linux/Cygwin machines to compile and run this, so if you don’t have a personal system with these features, you’ll need to use the iLab machines. The linked page has directions on how to set up an account, if you don’t already have one.

Specifics

The C portion of the program will need to demonstrate the difference between little- and big-endian encodings of numbers. To do this, it must take in one or more numbers at the command line; for each of these numbers, it must print out

You must create two assembly functions for this assignment:

Your C code must call writeHexASCII to generate the hexadecimal strings for its output, and it must call swapEnds to reverse endianness of each number. You may use printf to write the decimal form of the number, or to write the hexadecimal strings. Your C code must be valid ANSI C, as usual.

Your assembly code shouldn’t make calls to any outside functions, and it should be runnable on any 80486 or 80386 CPU in 32-bit protected mode. (I.e., precisely the environment we’ve used in class.)

You can write your assembly code in NASM or AT&T format; if it’s NASM, end your assembly file in .asm, and if it’s AT&T, end your file in .S (note the capital S).

Your output should have the following form:

$ ./your_program NUM1 NUM2 NUM3...
NUM1: HEX_FORM <-> REV_HEX_FORM = REV_DEC_FORM
NUM2: HEX_FORM <-> REV_HEX_FORM = REV_DEC_FORM
NUM3: HEX_FORM <-> REV_HEX_FORM = REV_DEC_FORM
...
Example input/output sequence:
$ ./your_program 1 512 4660
1: 00000001 <-> 01000000 = 16777216
512: 00000200 <-> 00020000 = 131072
4660: 00001234 <-> 34120000 = 873594880

By the by, don’t try to just compile some C code and hand it in. We can always tell. We can always tell.

Help

AT&T format

This is a horrible format for assembly language, but one that’s quite common, and it would behoove you to gain some familiarity with it. (It’s also useful if you want to integrate assembly code into C source code for GCC, or if you like sharing header files between C and assembly.)

There are a few big differences between AT&T and Intel/NASM formats:

If you don’t already have NASM...

...then you’ll need to download and build it. The NASM Sourceforge site is here; grab a source-code tarball (.tar.gz or .tar.bz2) and put it in your home directory somewhere. (Don’t grab binaries or RPMs or anything—you either can’t run them or can’t use them easily.)

Assuming you’ve gotten nasm-2.00.tar.*, extract the contents of the tarball by running

$ tar -zxvf nasm-2.00.tar.gz
for a .tar.gz, or
$ tar -jxvf nasm-2.00.tar.bz2
for a .tar.bz2. This will create a nasm-2.00 directory, with all the source inside it. Run this now:
$ cd nasm-2.00
$ ./configure --prefix=$HOME
... the build environment is set up ...
... a bunch of stuff prints out ...
$ make install
... everything is built and installed ...
... a bunch of other stuff prints out ...
At this point, assuming everything worked, you should have a NASM binary sitting in the bin subdirectory of your home directory. To run NASM, you can run ~/bin/nasm, or add the binary directory to your PATH variable. If you need help on this, talk to a TA or me.

Useful resources

Back to course page