Link Search Menu Expand Document

This lab writeup is a work in progress. Please do not begin if you see this message.

Lab 6 - Toy Assembly

Wouldn’t it be great if we did not need to write binary to program our machines? In class, we will soon be discussing x86-64 assembly, which is a more readable representation very close to the binary machine code, allowing us to program our computers (and the portal) more directly. In this lab, we will consider a simpler version of assembly language that directly maps to the Toy ISA we have been programming in over the past few weeks.

Lab Goals

After this lab, you should:

  1. Understand general format of assembly (similar to AT&T syntax of x86-64)
  2. Understand how ToyASM maps to our Toy ISA
  3. Be able to write code using assembly

Getting Started

In this lab, we will be using the CS portal to write and run our code. Please refer to Lab 1 for details on getting connected.

Toy Assembly

We will define a new language, ToyASM, that will make it easier to program our Toy ISA. It supports all of our icodes and operations from Lab 4, but with more human readable code than the bits we have been writing so far.

Each line in our code will consist of a single instruction with an operation and one or two operands, as follows:

operation source, destination

Definitions

Labels

When writing our ToyASM code, we may want to “remember” a location in our code so that we can jump to it later; i.e., to support loops and if statements. If a line in our code consists of only lower-case characters (a through z) followed by a colon, such as:

mylabel:

then this defines a label in our code. The assembler will remember the address of the next instruction in the code and replace the label with the correct memory address when producing the machine code.

Operations

Our Toy ISA has 14 total operations based on our 8 icode values and additional operations from icodes 5 and 6. We can represent all of those instructions using the following operations:

mov
Move/copy a value from one place to another. We can move from register to register (icode 0), memory at a register value to a register (icode 3), a register value to memory at a register’s value (icode 4), and memory at an immediate address to a register (icode 6.0).
add
Add a value from one place to a register’s value. We can add a register value to another register’s value (icode 1), or add an immediate value to a register’s value (icode 6.1).
and
Bitwise and a value from one place to a register’s value. We can and a register value to another register’s value (icode 2), or add an immediate value to a register’s value (icode 6.2).
neg
Negate a register’s value based on two’s complement (icode 5.1); updates the given register’s value.
not
Bitwise not of a register’s value (icode 5.0); updates the given register’s value.
lnot
Logical not of a register’s value (icode 5.2); updates the given register’s value.
jump
Compares the value in the first operand register to 0. If it is less than or equal to 0, then jump to the location (address) stored in the second operand register (icode 7).
movpc
Save the current pc value into the operand register (icode 5.3).
halt
A special instruction for our machines that will produce an instruction with reserved bit = 1, so that the code can be run on our simulators.

Operands

Our operands may take on multiple forms:

Registers
Registers are denoted using the %. For example, to write “register 2”, we would write %r2.
Literals
Literal values (immediates in our Toy ISA) are specified using a $. That is, to write the hex value 0x53 in our assembly language, we would write $0x53.
Memory Accesses
Our operand may be a value from memory instead of a value from a register or an immediate. Parentheses are used for a memory access as an operand; for example, to read memory at the address stored in register 1, we would write (%r1).
Labels
Since we are no longer writing bytes, jumping to a particular location in our code becomes tricky. Therefore, we can move a “label” into a register. Due to the limitations of our ToyISA, a label may only be moved into a register in the following way:
  mov mylabel, %r1

Note: when assembled, the binary generated from this instruction will move the address of the instruction following the mylabel: into register 1.

Example Programs

Assembling to Binary

We have provided an assembler to assemble (compile) our ToyASM to Toy ISA binary code. You can run this directly on portal using the following command:

/p/cso1/toyassemble my_asm_file.tasm

When run, our assembler prints out the corresponding hex digits for our binary program. You may then copy/paste this code into our online simulator or save it as a text file to use with your simulator from lab 4.

Your Task

In this lab, we will ask you to:

  1. Rewrite your fibonacci code from Lab 5 in our ToyASM.
    • Note how different and more readable your code is in the assembly
    • How does the assembled binary compare with the binary you wrote in Lab 5?
  2. Write X in ToyASM.

Check-off with a TA

To check-off this lab, show a TA

  • Your fibonacci ToyASM assembly code
  • X in assembly and running in a simulator

Copyright © 2023 John Hott, portions Luther Tychonievich.
Released under the CC-BY-NC-SA 4.0 license.
Creative Commons License