CMPS-2240 Lab-9
Intro to x86-64 Assembly

Gordon Griesel
Department of Computer and Electrical Engineering and Computer Science
California State University, Bakersfield

Introduction

Goals:
Learn to write an x86-64 assembly language program.

Files Needed:
All files on Odin at: /home/fac/gordon/p/2240/code/lab9/

Copy them to your Odin: 2240/9/ folder please.

links:
Makefile bare.asm driver.c goodbye.asm io.asm inout.asm lab9.asm nasm-help.txt gdb-guide.txt nasm-manpage.txt

Description

This lab introduces you to x86-64 assembly using NASM or Yasm. Both are x86 assemblers. Yasm has a few more capabilities than NASM. For the purposes of this class, either assembler will work fine.

Your job is to modify lab9.asm. The source currently prompts the user to input two integers from the keyboard and displays the greater of the two. Please modify the assembly code to:
. Display the sum of the two numbers.
. Display a message indicating when the numbers are equal.

Since integer I/O requires a conversion routine to convert from char to int you are going to link in the gcc standard c library and use printf and scanf rather than use assembly code to do this. Since the executable can be run on Odin, you can use gdb to debug your code. Note that you are linking a program written in C and a program written in x86 assembly.
This is ok because gcc will compile the C program into x86 machine language, and NASM/Yasm will compile the assembly source mnemonics into the same kind of machine language. Thus, the two programs can interact with each other as long as they follow the same conventions.
As we learned with MIPS, function arguments and output return values must be placed in specific registers for programs to work together. This is the calling convention.

Before beginning, study the comments on each line of code in bare.asm and inout.asm.

inout.asm prompts the user to enter a string from the keyboard (stdin) and then displays the entire string that the user entered to stdout (the screen). An x86-64 assembly file under linux will be assembled by nasm or yasm into an elf64 object file and then linked by ld into an elf64 executable. The file can then be executed on Odin. Some console commands to do this for nasm are:


 nasm -f elf64 lab9.asm    # this produces lab9.o
 gcc -o lab9 lab9.o        # gcc calls the linker

There is a convenient way to assemble and link your code. Since we are writing in x86 on an x86 machine we can use the make utility to handle the assembling and linking commands.

The copy commands above already placed a Makefile in your own folder.

So, to assemble and link inout.asm using the Makefile do this:

make inout

To remove .o object files do this:
make clean
To remove .o and executables do this:
make veryclean

All the code you need to complete this lab is in lab9.asm. x86-64 is CISC, is not load/store and is backwards compatible with 8 or so ISAs. "Not load/store" means that most instructions allow one of the operands to be a memory address. These three reasons make the x86 ISA instruction set larger than the MIPS instruction set.

Some programmers find that x86 is more difficult to understand than MIPS, but it really all depends on the individual.

One thing to notice is that the 64-bit register names in x86-64 begin with 'R' instread of 'E'. Add the instructions below into your code. Use printf to display the result. You can keep all existing code in lab9.asm.

                    ; add two numbers together - put sum in RCX
xor   rbx, rbx      ; effectively zero out rbx
xor   rcx, rcx      ; effectively zero out rcx
mov   rcx, [rbp-16] ; load rcx with value 16 bytes from base ptr
mov   rbx, [rbp-8]  ; load rbx with value 8 bytes from base ptr
add   rcx, rbx      ; add num1 + num2 - store in rcx

; There are other ways to achieve the same result.
; For example, since x86 is not load/store you can directly access memory as follows:

mov   rcx, [rbp-16] ; load rcx with value 16 bytes from base ptr
add   rcx, [rbp-8]  ; add num2 and num1 - store result in rcx

When you run your program, it should produce approximately the sample output below.


$ make
nasm -f elf64 -g -F dwarf lab9.asm    # -g -F dwarf adds debugging stuff
gcc -o lab9  lab9.o -lc -no-pie

$ ./lab9

Enter an integer: 21
Enter another integer: 5
The greater of 21 and 5 is 21.
The sum of 21 and 5 is 26.

$ ./lab9

Enter an integer: 23
Enter another integer: 23
23 and 23 are equal.
The sum of 23 and 23 is 46.

What to turn in

Your lab program on Odin at: /2240/9/lab9.asm plus your other files... /2240/9/Makefile /2240/9/bare.asm /2240/9/driver.c /2240/9/goodbye.asm /2240/9/inout.asm /2240/9/io.asm