| CompOrg Fall 2005 Lab |
|   CompOrg Home   |   asum   |   mult   |   dot product   |   Y86 Reference |
This lab involves writing programs (C functions) in Y86 assembly language. Y86 is a small subset of the IA32 instruction set, there is a list of Y86 instructions (and many code examples) in the text, lecture notes (Y86.pdf), and this reference: y86ref.html.
The C subroutine shown below sums the values in an array of integers:
int Sum(int *Start, int Count) {
int tot=0;
while (Count>0) {
tot += *Start;
Start++;
Count--; // Creates a Gui control panel for the ray tracer
}
return(tot);
}
|
asum.ys is complete Y86 assembly program that
includes this subroutine and a main function that calls it to test it
out. Your first task is to assemble this program (using yas - the
Y86 assembler) and test it (using yis - the Y86 simulator). The
assembler and simulator are located in
~hollingd/public/y86.
The sample y86 assembly programs are in
~hollingd/public/lab9.
> mkdir lab9 > cd lab9 > cp ~hollingd/public/lab9/asum.ys asum.ys > ~hollingd/public/y86/yas asum.ys > ~hollingd/public/y86/yis asum.yo
After running the simulator (yis) you will see output of all the
registers and memory locations that were changed by the asum
program. Based on the code (in asum.ys) and this output, you need to
determine what the return value of Sum()is
(the sum of the array passed to Sum). Just like with IA32
subroutines, Y86 subroutines put the return value in %eax.
Now change the asum.ys program so that the Sum subroutine is passed an array of 10 elements with the values 1,2,3...10. Reassemble and run the simulator and determine what the sum of the integers from 1 to 10 is.
Here is the entire asum.ys Y86 assembly program:
| asum.ys |
# Execution begins at address 0
.pos 0 # sets starting address
init:
irmovl Stack, %esp # Set up Stack pointer
irmovl Stack, %ebp # Set up base pointer
jmp Main # Execute main program
# Array of 4 elements is declared here
.align 4
array:
.long 0xd
.long 0xc0
.long 0xb00
.long 0xa000
Main:
irmovl $4,%eax # length of array
pushl %eax # Push length of array
irmovl array,%edx # put address of array in edx
pushl %edx # Push address of array
call Sum # Sum(array, 4)
halt
# C code for sum subroutine:
#
# int Sum(int *Start, int Count) {
# int tot=0;
# while (Count>0) {
# sum += *Start
# Start++;
# Count--;
# }
# return(tot);
# }
Sum:
pushl %ebp # stack frame setup
rrmovl %esp,%ebp #
mrmovl 8(%ebp),%ecx # ecx = Start
mrmovl 12(%ebp),%edx # edx = Count
irmovl $0, %eax # tot = 0 (eax)
andl %edx,%edx #
je End # jump if edx == 0
Loop:
mrmovl (%ecx),%esi # get *Start in esi
addl %esi,%eax # add to tot
irmovl $4,%ebx #
addl %ebx,%ecx # Start++
irmovl $-1,%ebx #
addl %ebx,%edx # Count--
jne Loop # Stop when edx is 0
End:
popl %ebp # restore stack frame
ret
.pos 0x100
Stack: # The stack goes here (at address 0x100)
|
You should write a Y86 assembly function named Mult that will multiply two unsigned integers. Recall that there is no multiply instruction in the Y86 instruction set, so you need to use repeated addition to accomplish this. The C prototype for the function looks like this:
unsigned int Mult(unsigned int a, unsigned int b);
Below is a Y86 main that will test your code (you need to add the code for the Mult subroutine):
| mult.ys |
# Execution begins at address 0 .pos 0 init: irmovl Stack, %esp # Set up Stack pointer irmovl Stack, %ebp # Set up base pointer Main: irmovl $5,%eax # second number passed to Mult pushl %eax # Push number irmovl $12,%eax # first number passed to Mult pushl %eax # Push number call Mult # Call multiply subroutine # answer is in eax halt # Your code for Mult goes here -------------- # ------------------------------------------- .pos 0x400 Stack: # The stack starts at 0x400 |
Notes:
You should write a Y86 assembly function named DotProd that will return the dot product of two vectors, each vector is represented by an array of integers. Both arrays are of the same size. Assuming the arrays are named A and B, and the length of the arrays is n, the value returned should be A[0]*B[0] + A[1]*B[1] + ... + A[n-1]*B[n-1].
Below is some sample main code you can use to test your function:
| dprod.ys |
# Execution begins at address 0 .pos 0 init: irmovl Stack, %esp # Set up Stack pointer irmovl Stack, %ebp # Set up base pointer jmp Main # Execute main program .align 4 # Array A (5 elements) a: .long 2 .long 4 .long 5 .long 1 .long 0 # Array b b: .long 3 .long 1 .long 2 .long 0 .long 6 Main: irmovl $5,%eax # length of arrays pushl %eax # Push length of array irmovl a,%edx # put address of array a in edx pushl %edx # Push address of array irmovl b,%edx # put address of array b in edx pushl %edx # Push address of array call DotProd # DotProd(a,b,5) halt # Your code for DotProd subroutine goes here: # You probably also want your Mult code! # ------------------------------------------- .pos 0x400 Stack: # The stack starts at 0x400 |
Notes: