Homework 5 - x86-64 Assembly

Information on clang and lldb

In lab 1, the CSO1 setup script added the necessary modules to be automatically loaded when you SSH to the portal nodes. (We added them to the .bashrc file that is run every time you connect.)

However, that automatic process seems to be broken, and we’re working with the department staff to figure out a better solution. In the meantime, when you SSH to the portal, you should start by issuing the following command:

module load gcc/14.2.0 clang/18.1.8

Introduction

In this assignment you need to write x86-64 assembly by hand. This is not something most programmers do often, but when it comes up in the workplace being one of the few there who can do it will help your company and make you shine.

We provide a base file (named distance.s) that includes the input and output interaction (in main and printNum) to test the code you will write. You may copy that file to your home directory (or cso1-code directory) by using the cd command to enter the directory in which you wish to work and then copying the file in:

cp /p/cso1/homework/distance.s .

It will be most helpful to cd into your cso1-code git-managed directory first to work on this assignment.

Once you have a local copy of the file, you can begin to write the functions below. Specifically, write your code where the comments say “TO DO: write this function”.

NOTE: You may NOT use a compiler or generative AI to write your code. You must write x86-64 assembly by hand. Using a compiler or generative AI will result in a 0 for this assignment.

Writing your code

We are expecting that you will write your code in a command-line editor (vim, nano, etc) on the portal. If you need to refresh, please review Lab 1.

Using an IDE (such as Visual Studio Code, IntelliJ IDEA, etc, or an online editor or compiler will result in an immediate 0 on the assigment. Sorry to be strict on this, but one of the goals of this course is to gain familiarity with command-line tools. Remember, we’ll get to VSCode later.

Why a CLI editor?

It is common to interact with servers that do not have their own monitors. In these cases, you typically attach to the server via ssh and have access only to a terminal, not a full windowing environment. The more comfortable you are with doing common programming tasks in the terminal, the better these experiences will be.

Testing your code

We recommend using git to version and test your code. Each time you make changes, you can git add, git commit, and git push to keep a backup copy of your changes. You can also use git to git pull your changes to your laptop to submit to Gradescope.

For example:

  1. Use a git project for this HW and check it out on both your laptop and the server. You can use the same project you made in Lab 6 or a new one for just this HW
  2. Copy the distance.s file into that project directory on the portal (in your home directory) and git add distance.s to tell git to track it
  3. Edit and test on the portal
    1. edit with vim or nano
    2. compile with clang distance.s and run with ./a.out
  4. When you want to submit it to Gradescope
    1. commit your edits (e.g. git commit -a -m 'I think I got distance working now')
    2. push your committed edits (e.g. git push)
    3. tell the copy on your laptop to pull (e.g. git pull)
    4. submit the copy on your laptop to Gradescope

This way you’ll both (a) have a backup of every version, (b) have a copy on the server in case something happens to your laptop (and vice versa), and (c) know you’re using the same compiler, processor variant, etc, that we are.

Testing your code

When we are ready to run code, we need to compile (well assemble and link) our code so that we can run it. We’ll need to do this every time we make a change to the code!

  1. Compile your code into something that can be run as a program. Use the following command to compile your code.
       clang distance.s
    

    Once run, this compiler will create a new file, a.out, that is the executable program.

  2. Run your code by executing a.out in the terminal. To do that, you’ll need to include the path to your program. That means, you can run the code as:
       ./a.out
    
  3. Sometimes, most times (actually), it will be helpful to step through your code while it is running so that you can see how it updates the registers (and memory). You likely did this with the ToyISA using either the simulator you wrote or the one on the course website. For real programs in x86-64, we can use the debugger lldb. More information about the debugger can be seen on our Using the Debugger Reading.
    • Run the debugger on your code with the following command on the terminal:
         lldb a.out
      
    • From there, you can set a break point at any of your functions, such as:
         b product
      
    • Then run your code stopping at that breakpoint with run.
    • Review more of the examples in the reading linked above. We’ll share more techniques for the debugger in class.

Write three functions

In AT&T syntax x86-64 assembly, write three routines: one that computes the product of two integer numbers (without multiplication), one that computes the power of one number to the other power(a,b) (using your product function), and one that calculates the squared Euclidean distance between two 2D points (using your power function).

It should be possible to assemble your code by typing clang distance.s to generate a file, a.out, that can be run by by typing ./a.out. When run, it should1 ask for four integers and display the product of the first two, the power of the third raised to the fourth integer power, and the squared Euclidean distance from the first two (x1, y1) to the second two (x2, y2).

Product

The first subroutine, product, should compute and return the product of the two integer arguments. It must not use multiplication instructions. It must compute this iteratively, not recursively. You may follow your logic from Homework 3 or Homework 4.

Updated 10/16: Either parameter may be 0, but you may assume that neither will be negative. That is, we’ll only test your code with non-negative values.

Power

The second subroutine, power, should take two arguments, such as x and y, and compute and return \(x^y\). It must use the product routine you wrote to do this, not x86-64 multiplication instructions or other routines you did not write. It must compute this recursively, not iteratively. You may find the logic you used for Homework 4 helpful when writing power.

There are other correct solutions, but a simple one might follow an approach like the following pseudo-code:

function power(x, y)
    if y == 0 then
        return 1
    else if x == 0 then
        return 0
    else
        return product(x, power(x, y-1))
    end if
end function

You may assume that both arguments are non-negative and that the result can fit in a single 64-bit register. We define \(x^0 = 1\) for all \(x\) and \(0^n=0\) for all \(n \neq 1\).

Distance

The third subroutine, distance, should take two 2D points \((x_1, y_1), (x_2, y_2)\) as four arguments in the order \(x_1, y_1, x_2, y_2\) and calculate the squared Euclidean distance between the points. The squared Euclidean distance is calculated as \((x_2 - x_1)^2 + (y_2 - y_1)^2\). It must use the power routine you wrote to do this, not x86-64 multiplication or other routines you did not write. It must compute this iteratively.

There are other correct solutions, but a simple one might follow an approach like the following pseudo-code:

function distance(x1, y1, x2, y2)
    z = x2 - x1
    w = y2 - y1
    a = power(z, 2)
    b = power(w, 2)
    return a + b
end function

You may assume that the parameters are signed integers and that the result can fit in a single 64-bit register.

Submit

Submit your assembly as distance.s via Gradescope.

NOTE: You may NOT use a compiler to write your code. You must write x86-64 assembly by hand. Using a compiler or generative AI will result in a 0 for this assignment.

Important!

  • If you used outside sources (including Generative AI) in any way in relation to this homework (which, per our course policy, should NOT include having Generative AI write any portion of the assignment for you, you must upload a sources.txt file listing your sources and how you used the information provided (such as by Generative AI) when completing the assignment.
  1. Along the way, you might accidentally write code that runs forever. If the program freezes while running, try pressing Ctrl+C to interrupt it. 


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