CMPS-2240 Lab 7
Intro to x86-64 Assembly

Eddie Rangel
Department of Computer and Electrical Engineering and Computer Science
California State University, Bakersfield

Notice:
Due: Wednesday Nov. 2nd by 4pm

Introduction

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

Files Needed:
All files at: http://cs.csubak.edu/~erangel/cmps2240-f16/code/lab8/
Copy them to your area like this:
cp /home/stu/erangel/public_html/cmps2240-f16/code/lab8/* .
or like this
scp sleipnir.cs.csubak.edu:/home/stu/~erangel/cmps2240-f16/code/lab8/* .

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 lab8.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 sleipnir, 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 sleipnir. Some console commands to do this for nasm are:


 nasm -f elf64 lab8.asm    # this produces lab8.o
 gcc -o lab8 lab8.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 and executables do this:

make clean

All the code you need to complete this lab is in lab8.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 lab8.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 lab8.asm    # -g -F dwarf adds debugging stuff
gcc -o lab8  lab8.o -lc

$ ./lab8

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

$ ./lab8

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 lab8.asm must be in the correct directory on Sleipnir.
directory name: /home/stu/you/2240/8/
Replace you with your own Sleipnir username!