| CompOrg Fall 2005 |
|   CompOrg Home   |   Assignment   |   Sample Test Code   |   How to submit   |   Grading   |   Hints |
| Assignment |
This assignment involves the creation of some IA32 subroutines. You are given a description of the C interface to each subroutine (as a C function prototype) and you need to write IA32 assembly code. Feel free to look at code generated by gcc, but don't submit IA32 code generated by gcc! (You need to write these subroutines!).
You are to write IA32 assembly code (that can be compiled with gcc running on the CS BSD machines) for the C functions described below. It is essential that your functions follow the names and arguments described below (we will write code that calls your functions!).
Your function definitions will be linked with our main
code, so you just need to write the code for the three functions listed
below. Feel free to write other functions as well, the only
requirement is that you include the functions listed below.
int pow(int x, int y);
You need to write the function pow that
returns the integer value of x raised to the
yth power (xy). Both
x and y are 32 bit integers.
Your function must return the correct value for any
x, y for which the correct answer is
representable as a 32 bit signed int. The parameter
x may be negative, but y will always be
a non-negative integer.
Below is the IA32 assembly framework for your function (feel free
to use this as a starting point). This code includes the subroutine
setup and termination code, and also gets the value of x
and put's it in register %eax, and the value of
y is put into register %edx.
NOTE: The code below saves and restores registers ebx,
esi and edi, this means that you can use
these registers for anything you want in your function. (According to
the
gcc register usage conventions, you can always use %eax,
%ecx and %edx for anything you want.)
|
We won't call your pow function with parameter values
that result in a number that can't be represented in a 32 bit int, and
we won't call with a negative value for y, so you do not
need to include code that makes sure x and y
are within any range of values. A value of 0 for x or
y is possible!
void reverse(char *s);
You need to write the function reverse that
reverses the order of bytes in an ASCII (null terminated) string
that starts at the address specified.
Here is the IA32 function beginning and end, once again feel free
to start with this. The code below puts s in register
%eax. Note that
the function has no return value, so it doesn't matter what is in
%eax when the function returns - the function modifies the array.
NOTE: The code below saves and restores registers ebx,
esi and edi, this means that you can use
these registers for anything you want in your function.
|
NOTE: Keep in mind that when dealing with bytes (C char), you can
use byte registers like %bl, %bh, %al, %ah, but remember
that register %al is part of %eax.
int count_elem(int *a, int n, int x);
You need to write the function count_elem that returns
the number of array elements (in array a) whose value is
the same as x. The parameter n is the number
of elements in the array (and a is the starting address
of the array).
Your function should return 0 if it doesn't find any elements that
match x, or if the size of the array (n) is
0.
Keep in mind that each array element is 4 bytes!
Once again, below is some code to get you started:
|
| Sample Test Code |
We will be using our own main to test your functions,
so you must not include a main in the assembly file you
submit. Below is a sample main written in C that you can
use as a starting point for testing your code. To combine this with
your assembly code you can either:
Use gcc -S main.c to generate
main.s, then put this in the same file as the assembly
code for your functions.
If your three functions are defined in the file
hw2.s, you can tell the compiler to build an executable
like this:
gcc -o hw2 hw2.s main.c
|
The output produces by the above main code should look like this:
> ./hw2 Reverse(Hello World) is dlroW olleH Reverse again give Hello World pow(3,0) = 1 pow(3,2) = 9 pow(3,4) = 81 pow(3,6) = 729 pow(3,8) = 6561 Array is [ 1 3 2 1 4 0 -3 1 2 4 ] number of 0s is 1 number of 1s is 3 number of 2s is 2 number of 3s is 1 |
| How to submit |
Submission of your homework is done using WebCT (webct.rpi.edu). Once you log in to WebCT and access the CompOrg site, you should click on assignments, then select HW2. Upload your hw1.s file to webct. Do not submit a file that includes a main function! (we will write our own test program).
If there is anything special about your code (for example if it doesn't work for all inputs, or only includes one of the two functions), put this information in a file named README and submit this as well. Feel free to put anything else you want in your README file (was this hard? did you learn anything?, etc...).
Don't send compiled code, only send your assembly program!
We will be testing on monica.cs.rpi.edu, make sure your code will work on monica!
Your code must be commented!
Multiple Submissions: You can resubmit as many times as you want, WebCT will make sure we get the last file you submit.
| Grading |
Grades will be determined by testing your functions with various parameter values. We will only test your functions with reasonable parameter values so you don't need to include code in your functions that validates the parameters.
Each function is worth 1/3 of the grade.
| HINTS/Suggestions: |
Feel free to write C code to get started (it might be good to develop algorithms in C before converting to assembly). You can certainly ask gcc to convert your C to assembly so you can look at some assembly code, but you must write the code you submit! Keep in mind that gcc will produce a lot more code than is necessary, and that we can easily detect gcc produced code.
Start simple - write assembly subroutines that do something simple like just return the value 10:
pow:
pushl %ebp
movl %esp, %ebp
movl $10,%eax
leave
ret
Once this is working (when called from your C test code), start to add the actual code needed.
Use gdb! It is somewhat painful to add calls to printf in assembly language, so rather than debugging via printf, use gdb to trace the execution of your functions.