CompOrg Fall 2005 Lab

Lab #9 - Y86 Programming and Simulator

11/2/2005


A Y86 Instruction Reference is available here
Y86 Simulator (yis) manual


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.


Array Sum subroutine in Y86

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)

Multiply Subroutine

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:


Dot Product of two vectors

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: