CSCI 237

Computer Organization

Home | Schedule | Assignments | Links | Williams CS

Lab 3: Y86-64

Assigned: Tuesday, April 7
Due Date: Tuesday, April 14 at 10:00pm.
Submissions: Submitting requires two independent steps:
1. Commit and push your solutions in your private repository on GitLab.
2. Submit your solutions to the autograder using:
   $ submit237 3 sum.ys rsum.ys copy.ys

Overview

This lab will give you experience writing code directly in assembly. It will also increase your familiarity with Y86-64, the idealized language we are using in our study of processor design and implementation. Specifically you will write some simple Y86-64 programs and become familiar with the Y86-64 tools.

Instructions

For this assignment, you will be given a private github repository with starter code. You will find the following files in your starter repository:

The directory sim contains a copy of the Y86-64 tools. You will be doing all of your work inside this directory. To build the Y86-64 tools, change to the sim directory and make:

         $ cd sim
         $ make clean; make 

Programming in Y86-64

You will be working in the directory sim/misc for this lab. Your task is to write and simulate (i.e., run your code using the Y86 tools) the following three Y86-64 programs. The required behavior of these programs is defined by the functions in examples.c. Be sure to put your name in a comment at the beginning of each program. You can test your programs by first assembling them with the program YAS, and then running them with the instruction set simulator YIS. Reviewing these slides may be helpful (and may even include some starter code...).


In all of your Y86-64 functions, you should follow the x86-64 conventions for passing function arguments, using registers, and using the stack. This includes saving and restoring any callee-save registers that you use.


For reference, here is len.ys, an example Y86 program (from the slides above) that sums the elements in a null-terminated array. Also, here is a nice web-based graphical Y86-64 simulator.

Program 1: Iteratively sum linked list elements (sum.ys)

Write a Y86-64 program sum.ys that iteratively sums the elements of a linked list. Your program should consist of some code that sets up the stack structure, invokes a function, and then halts. In this case, the function should be Y86-64 code for a function (sum_list) that is functionally equivalent to the C sum_list function shown in examples.c. Note that you do not need to worry about a Main function, but you do need to make sure the address of your array is being passed to your function. You can test your program using the following three-element list:

	# Sample linked list
	.align 8
	ele1:
		.quad 0x00a
		.quad ele2
	ele2:
		.quad 0x0b0
		.quad ele3
	ele3:
		.quad 0xc00
		.quad 0
	

This starter code should help you to get started.

Program 2: Recursively sum linked list elements (rsum.ys)

Write a Y86-64 program rsum.ys that recursively sums the elements of a linked list. This code should be similar to the code in sum.ys, except that it should use a function rsum_list that recursively sums a list of numbers, as shown in the C function rsum_list. Test your program using the same three-element list you used for testing sum.ys. (The sum should be the same.)

Program 3: Copy a source block to a destination block (copy.ys)

Write a program copy.ys that copies a block of words (i.e., a contiguous chunk of memory) from one part of memory to another (non-overlapping) area of memory, computing the checksum (xor) of all the words copied. Your program should consist of code that sets up a stack frame, invokes the function copy_block, and then halts. The function should be functionally equivalent to the C function copy_block. Test your program using the following three-element source and destination blocks:

	
	.align 8
	# Source block
	src:
		.quad 0x00a
		.quad 0x0b0
		.quad 0xc00
	# Destination block
	dest:
		.quad 0x111
		.quad 0x222
		.quad 0x333
	

For reference, here is sim/misc/examples.c:

	1  /* linked list element */
	2  typedef struct ELE {
	3  	 long val;
	4 	 struct ELE *next;
	5  } *list_ptr;
	6
	7  /* sum_list - Sum the elements of a linked list */
	8  long sum_list(list_ptr ls)
	9  {
	10 	 long val = 0;
	11 	 while (ls) {
	12 		val += ls->val;
	13 		ls = ls->next;
	14 	 }
	15 	 return val;
	16  }
	17
	18  /* rsum_list - Recursive version of sum_list */
	19  long rsum_list(list_ptr ls)
	20  {
	21 	  if (!ls)
	22 		return 0;
	23 	  else {
	24 		long val = ls->val;
	25 		long rest = rsum_list(ls->next);
	26 		return val + rest;
	27 	  }
	28  }
	29
	30  /* copy_block - Copy src to dest and return xor checksum of src */
	31  long copy_block(long *src, long *dest, long len)
	32  {
	33 	  long result = 0;
	34 	  while (len > 0) {
	35 		long val = *src++;
	36 		*dest++ = val;
	37 		result ^= val;
	38 		len--;
	39 	  }
	40 	  return result;
	41  }
	

And here is an equivalent version of sim/misc/examples.c, without the typedef or complex pointer updates:

	1  /* linked list element */
	2  struct ELE {
	3  	 long val;
	4 	 struct ELE *next;
	5  };
	6
	7  /* sum_list - Sum the elements of a linked list */
	8  long sum_list(struct ELE *ls)
	9  {
	10 	 long val = 0;
	11 	 while (ls) {
	12 		val += ls->val;
	13 		ls = ls->next;
	14 	 }
	15 	 return val;
	16  }
	17
	18  /* rsum_list - Recursive version of sum_list */
	19  long rsum_list(struct ELE *ls)
	20  {
	21 	  if (!ls)
	22 		return 0;
	23 	  else {
	24 		long val = ls->val;
	25 		long rest = rsum_list(ls->next);
	26 		return val + rest;
	27 	  }
	28  }
	29
	30  /* copy_block - Copy src to dest and return xor checksum of src */
	31  long copy_block(long *src, long *dest, long len)
	32  {
	33 	  long result = 0;
	34 	  while (len > 0) {
	35 		long val = *src;
	36 		src++;
	37 		*dest = val;
	38 		dest++;
	39 	        result ^= val;
	40              len--;
	41 	  }
	42        return result;
	43  }
	

Resources