⚠️ This is not the current iteration of the course! Head here for the current offering.

Section 3: Assembly

This section contains a series of excercises to help get you more familiar with the Assembly Language and using GDB (GNU Debugger). By the end of it, we hope you'll be an Assembly superhero!

Warmup: Assembling the Right Tools

During this warmup, we'll be going over key parts of assembly like registers, then looking at some sample assembly programs.

WARMUP A. In x86-64 assembly, which register holds the return value of functions?

WARMUP B. Consider the register %rax. How many subregisters does %rax have? What are their names and sizes?

WARMUP C. What is the size (in bytes) of a long in x86-64 assembly?

Question 1: Fun!

Now it's time to have some fun! Unfortunately having fun is not quite that simple. Everyone has fun in their own special ways. In order for your computer to have some fun, you'll need to input a specific argument.

There are six different fun-having functions in this portion of the section. Each fun function will return either 0 (if fun is had) or something else (if no fun is had). The goal is to find out the arguments so each fun-having function can have fun!

To compile the program, run make inside the section3 directory in the section code.

To run a fun function, use the following command format:

$ ./fun [number of func] [argument to func]

For example:

$ ./fun 1 "CS300!"

Will run the first fun function (fun_one) with input CS300!.

In this part of the section, we will use the objdump tool to look at the assembly code for executables we have already compiled, and we will use GDB to investigate the behavior of fun-inducing functions. GDB helps us analyze how each fun function responds to the inputted argument. (Check out this GDB cheatsheet for a brief overview of useful commands and their usage.)

NOTE: If you are on an Apple Silicon or other ARM64 device, please consult the README.apple file in the section code for how to run GDB for this section.

Note that the call instruction calls a function; in x86-64, register %rdi (or its sub-registers) hold the first argument to a function at the time of the call instruction.

QUESTION 1A. What argument will allow fun_one to have fun? For reference, its assembly is below:

fun_one:
	subq	$24, %rsp
	movq	%rdi, 8(%rsp)
	movq	8(%rsp), %rax
	movl	$33, %esi
	movq	%rax, %rdi
	call	strchr@PLT
	testq	%rax, %rax
	je	.L20
	movl	$0, %eax
	jmp	.L21
.L20:
	movl	$-1, %eax
.L21:
	addq	$24, %rsp
	ret

QUESTION 1B. What argument will allow fun_two to have fun? For reference, its assembly -- in objdump output format -- is below. Note that %rdi contains the first argument to a function called as before, %rsi contains the second argument, and %rdx contains the third argument.

0000000000001352 <fun_two>:
    1352:       sub    $0x18,%rsp
    1356:       mov    %rdi,0x8(%rsp)
    135b:       mov    0x8(%rsp),%rax
    1360:       mov    $0x0,%edx
    1365:       mov    $0x0,%esi
    136a:       mov    %rax,%rdi
    136d:       callq  1060 <strtol@plt>
    1372:       add    $0x1,%eax
    1375:       add    $0x18,%rsp
    1379:       retq

QUESTION 1C. What argument will allow fun_three to have fun? Let's investigate using GDB in layout asm mode.

Note the following:

QUESTION 1D. What argument will allow fun_four to have fun? Use objdump or GDB to investigate. The register table from the lecture notes may come in handy.

QUESTION 1E. What argument will allow fun_five to have fun? For reference, its assembly is below:

fun_five:
	movq	%rdi, -8(%rsp)
	movq	-8(%rsp), %rax
	movzbl	(%rax), %eax
	testb	%al, %al
	jne	.L31
	movl	$-1, %eax
	ret
.L31:
	movq	-8(%rsp), %rax
	movzbl	(%rax), %edx
	movq	-8(%rsp), %rax
	addq	$1, %rax
	movzbl	(%rax), %eax
	cmpb	%al, %dl
	je	.L33
	movq	-8(%rsp), %rax
	addq	$1, %rax
	movzbl	(%rax), %eax
	movsbl	%al, %eax
	ret
.L33:
	addq	$1, -8(%rsp)
	jmp	.L31

QUESTION 1F. What argument will allow fun_six to have fun? Investigate this question using GDB.

Question 2: Deciphering Assembly

For whatever reason, you happen to come across the following assembly code. Let's get a closer look at what this program is doing!

	.file	"q1.c"
	.text
	.section	.rodata
.LC0:
	.string	"%d\n"
	.text
	.globl	func
	.type	func, @function
func:
	subq	$24, %rsp
	movl	$42, 8(%rsp)
	movl	$0, 12(%rsp)
	jmp	.L2
.L3:
	movl	12(%rsp), %eax
	movl	%eax, %esi
	leaq	.LC0(%rip), %rdi
	movl	$0, %eax
	call	printf@PLT
	addl	$1, 12(%rsp)
.L2:
	movl	12(%rsp), %eax
	cmpl	8(%rsp), %eax
	jl	.L3
	movl	$1, %eax
	addq	$24, %rsp
	ret
	.size	func, .-func
	.globl	main
	.type	main, @function
main:
	subq	$8, %rsp
	movl	$0, %eax
	call	func
	addq	$8, %rsp
	ret
	.size	main, .-main
	.ident	"GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0"
	.section	.note.GNU-stack,"",@progbits

QUESTION 2A. What does the function func return?

QUESTION 2B. What does the function main return?

QUESTION 2C. What C code could have generated func?


Acknowledgements: Material in this section was originally developed for Harvard's CS 61 course. We are grateful to Eddie Kohler for allowing us to use the material for CS 300.