Computer Science 220
Assembly Language & Computer Architecture

Fall 2011, Siena College

Lab 1010: ISA Comparisons
Due: 4:00 PM, Monday, December 12, 2011

During this week's lab meeting, you will learn about instruction set architectures other than MIPS. Be sure you understand everything here - all topics in this lab handout are potential final exam question topics.

You may work individually or with a partner on all parts of this lab.

There are a series of questions you need to answer and turn in by email. You may wish to open an email draft or start editing a document to record your answers as you go. Start by placing your name and the name of your partner (if you have one) in this document.

Addressing Modes

Before we consider specific instruction set architectures, we review and give examples of addressing modes. The addressing mode of of each operand of a machine instruction determines how the instruction finds the data specified by that operand (either source or destination).

Some very common addressing modes include:

Question 1: Identify the addressing mode used for each operand in the following MIPS instructions (2 points):

add $4, $5, $6
ori $7, $4, 16
lw $8, 0($12)
sw $9, -14($8)

Question 2: MIPS does not have a register indirect addressing mode (without offset). But we have been doing the equivalent in many of our programs. How do we achieve the equivalent using the modes it does have? (1 point)

We used register indirect with offset addressing for accessing array elements where we had a constant subscript:

lw $5, 16($6)   ; load a[4] if $6 is a pointer to a

We also saw this when saving and restoring registers on the stack:

sw $9, -4($sp)  ; store $9 on stack at offset -4

Now, suppose we have a C structure (think Java class if C structures upset you too much):

struct ratio {
  int numerator;
  int denominator;
};

and the following C code, where r is a pointer to one of these structures:

  int n;
  int d;
  n = r->numerator;
  d = r->denominator;

Question 3: If the variables r, n, and d are assigned to registers $9, $10, and $11, respectively, give MIPS code that would implement the above statements. (2 points)

There are also some less-common addressing modes worth noting:

Question 4: MIPS certainly does not have this addressing mode, but if it did, we would be able to write an instruction like this:

add $3, $2, 4($7,$8.w)

What sequence of real MIPS instructions would peform the same function? (1 point)

Question 5: How could these addressing modes help when compiling a loop that computes the sum of all elements of an array? (1 point)

More Complex Instuctions

All MIPS machine instructions are, by design, very limited in what they can do. This is not true of all architectures. Consider some examples from other architectures:

Question 6: Give C or Java code equivalent to the code above. You may assume that there are variables data and num that contain a pointer to the start of an array and the number of elements in that array, respectively. (2 points)

Question 7: Which MIPS design principles would a similar instruction in MIPS violate? Could you come up with an instruction format that would work for it? (1 point)

RISC vs. CISC

In class, we are studying how to implement the MIPS ISA directly in hardware, including a pipelined implementation that handles complexities like data forwarding and hazard detection.

This is possible in a course such as this because of the simplicity of its design. MIPS instructions each have a single, simple function, all instructions are the same size (one 32-bit word), and there are very few addressing modes.

These are some of the features common to Reduced Instruction Set Computer (RISC) architectures, of which MIPS is an excellent example.

CISC Architectures

Other architectures are Complex Instruction Set Computer (CISC) architectures. Examples include IBM mainframe architectures, the Digital Equipment Corporation PDP-11 and VAX architectures, the Motorola 68000 series, and the Intel x86 family of architectures.

As the name indicates, and as you saw in the previous section, instructions in a CISC architecture can be quite complex.

CISC architectures are too complex to be implemented directly in hardware. In these cases, an implementation might involve a simpler hardware (a microarchitecture) and an interpreter that is used to execute instructions, guided by a microprogram.

Decoding and executing an instruction can require several steps (microinstructions), and the more complex the instruction (more operands, etc) the longer it will take.

Typical CISC architecture characteristics:

If you have to program directly in assembly language, a CISC architecture can make this task easer. However, compilers may make use of only a subset of available the available instructions.

RISC Architectures

Researchers (including our text authors) in the early 1980's advocated for the RISC approach.

Characteristics of RISC architectures:

If you have to program by hand, RISC architectures will be more difficult. The task is easier for, and intended to be done by, a compiler.

Question 8: One of the above items states that "instructions support a small number of addressing modes, with each opcode requiring specific addressing modes for its operand". But in MIPS, we can add a register to a register or a register to a constant. Does MIPS fit the statement? (1 point)

Question 9: Why do the pipelines in a RISC architecture need to be short? (1 point)

Sun SPARC

Sun Microsystems' SPARC architectures enjoyed a long period of success from the early 1990's to the early 2000's.

SPARC is a RISC architecture, and contains many of the same features as MIPS.

Register Windows

A RISC system may have hundreds of registers in its register file.

One way to organize these registers is to treat the register file as circular and give each routine a "view" of a limited subset of these registers at any given time.

Read the first SPARC has many, many registers but only 32 visible at any given time.

Question 10: Give a few reasons why might one not wish to expose hundreds of registers to all subroutines. (1 point)

One subset of registers is designated as "globals" and are visible to all routines.

Then, each routine has three subsets of registers

The "outs" of a routine become the "ins" of a subroutine that it calls.

Much of what we could do with the stack for parameter passing and local variable storage can be replaced with this.

We eliminate some of the problems of registers getting clobbered by subroutines and we speed function calls by reducing memory accesses needed to pass parameters on the stack.

But what if we have a deep call stack and we run out of registers? We can't just clobber things, so we'd need to keep a stack also for those cases.

The actual implementation involves "pretending" to write things to the stack, but it only actually does this ("spill" to the stack, and "fill" from the stack to restore) if necessary given the current state of the register file.

Problem: what about functions with more parameters than can be passed in the register window? We still need the stack for those.

Question 11: Compare the SPARC with register windows where there are 8 globals, 8 ins, 8 locals, and 8 outs with the MIPS register file we know so well. How many parameters can be passed to a function without worrying about using the stack in each? How many values can be returned in each? What differences are there between a programmer's usage of the MIPS t-registers and the SPARC "locals"? (3 points)

Other SPARC Features

A few final notes about SPARC:

x86/IA-32 ISA

This section presents some highlights of the text's discussion of the Intel x86 architecture in Section 2.17. Now that you know something about the MIPS ISA and its simplicity, that section will make for interesting reading.

A Brief History of the x86

x86/IA-32 Overview

Question 12: Based on these restrictions, give an example of a single MIPS instruction that peforms an operation that could not be done in a single x86 instruction. (1 point)

x86 Basics: Registers, Data Types, and Memory

A diagram of the main registers can be found in Figure 2.36.

Question 13: How would you increment a value in memory in MIPS? (1 point)

x86 ISA

x86 Wrapup

Just how complex is the x86 ISA today?

See Figure 2.43 for a summary.

Question 14: COD Exercise 2.38, parts 1b, 2b, and 3b, only. (3 points)

Comparing Assembly Language Programs

We will consider the assembly language code generated from a few simple C programs for some of the ISAs we consider:

See Example:
~jteresco/shared/cs220/examples/assembly

Copy these to your own account or computer.

Here, you will find two C files, each of which contains a simple C function. You will also find compiler-generated assembly language code for 5 architectures: x86, M68K, MIPS, PPC, and SPARC.

You will notice that while each architecture has a very unique set of instructions, register names, and addressing modes, each is unmistakeably an assembly language program.

Consider the files multiply-mips-gcc.s, multiply-i386-gcc295.s, multiply-sparc-cc.s, multiply-sparc-gcc.s, multiply-m68k-gcc.s, and multiply-ppc-gcc.s when answering the following questions.

Question 15: Identify the register or memory location being used to store the variable product in each program. (1 point)

Question 16: Identify the instruction that performs the right shift in each program. (1 point)

Question 17: Identify the instruction that performs the conditional branch for the if (y & 1) in each program. (1 point)

Question 18: Find an example of a branch delay slot in each "sparc" program. Which one makes effective use of the branch delay slots? (1 point)

Submission and Grading

This lab is graded out of 25 points. The points per question are specified above.

By 4:00 PM, Monday, December 12, 2011, please submit your responses to the questions by email to jteresco AT siena.edu. You may supplement your submission with a handwritten response to some or all questions.