Last Updated: 2024-09-29 Sun 17:16

CMSC216 HW05: Assembly Basics

CODE DISTRIBUTION: hw05-code.zip

  • Download the code distribution
  • See further setup instructions below

CHANGELOG: Empty

1 Rationale

The basics of working with existing assembly language code are covered in this HW. Generating assembly from C and analyzing it along with adding to existing assembly code and compiling it are covered.

Associated Reading / Preparation

  • Bryant and O'Hallaron: Ch 3.1-3.7 on assembly code instructions in x86-64.
  • Any overview guide to x86-64 assembly instructions such as Brown University's x64 Cheat Sheet
  • Knowledge of how gcc can generate assembly code from C code is required and should be reviewed from the textbook and/or lecture materials.

Grading Policy

Credit for this HW is earned by taking the associated HW Quiz which is linked under Gradescope. The quiz will ask similar questions as those that are present in the QUESTIONS.txt file and those that complete all answers in QUESTIONS.txt should have no trouble with the quiz.

Homework and Quizzes are open resource/open collaboration. You must submit your own work but you may freely discuss HW topics with other members of the class.

See the full policies in the course syllabus.

2 Codepack

The codepack for the HW contains the following files:

File Description
QUESTIONS.txt Questions to answer
ipow_for.c Problem 1 C file for ipow() function
ipow_while.c Problem 1 C file for ipow() function
ipow_main.c Problem 1 main() function
coins_main.c Problem 2 main() function
coins.h Problem 2 C header
coins_funcs.c Problem 2 C functions to be implemented in assembly
coins_funcs_asm.s Problem 2 Incomplete Assembly functions

3 What to Understand

Ensure that you understand

  • How to compile C code to assembly
  • Some basics of registers, operations, and control flow in assembly and how they correspond to C programs
  • Basics of writing assembly code and register passing conventions for functions.

4 Questions

Analyze the files in the provided codepack and answer the questions given in QUESTIONS.txt.

                           _________________

                            HW 05 QUESTIONS
                           _________________


Write your answers to the questions below directly in this text file to
prepare for the associated quiz. Credit for the HW is earned by
completing the associated online quiz on Gradescope.


PROBLEM 1: ipow Assembly
========================

  The code pack contains the following files.
  - ipow_for.c : ipow function using a for loop
  - ipow_while.c : ipow function using a while loop
  - ipow_main.c : main function to call the above
  Both the for and while versions define the same function which has a
  meaning which should be obvious.

  Compile and run these as programs using either of the below:
  ,----
  | > gcc ipow_main.c ipow_for.c
  | > ./a.out 3 5
  | 3^5 = 243
  | 
  | OR
  | 
  | > gcc ipow_main.c ipow_while.c
  | > ./a.out 3 5
  | 3^5 = 243
  `----


A
~

  Compile ipow_for.c to assembly code. Look up how to do this with gcc
  if you did not take notes on how to do so from lecture. Make sure to
  disable optimizations by gcc when compiling.

  Paste the command you used and the generated assembly for the
  resulting ipow_for.s as you answer below.


B
~

  Similarly, compile the file ipow_while.c to assembly and compare the
  resulting ipow_while.s to ipow_for.s.
  - If you see differences, describe what these differences are and why
    the generated code varies between the two.
  - If you see similar code, describe why this might be.


C
~

  Examine the generated assembly code in ipow_for.s carefully. Based on
  the "assignments" of initial values to registers and the use of
  registers in operations like multiplication, addition, and comparison,
  attempt to draw a correspondence between the assembly registers and C
  variables. Ensure you identify the C variables
  - argument base: which register contains the 1st function argument?
  - argument exp: which register contains the 2nd function argument?
  - local pow which is also the return value
  - local i

  For your answer, paste in an annotated copy of the ipow_for.s which
  shows labels the correspondence of registers to C variables and
  describes how most of the assembly lines correspond to lines in the C
  code. You may skip lines like
  ,----
  | .cfi_startproc
  | .type	ipow, @function
  | .size	ipow, .-ipow
  | .ident	"GCC: (GNU) 7.3.0"
  | .section	.note.GNU-stack,"",@progbits
  `----
  which are assembler directives beyond the scope of our current
  interest.


D
~

  Some compilation environments may produce the following odd
  instruction sequence:
  ,----
  | rep ret
  `----

  The `ret' instruction is a function return but `rep' is supposed to
  have a different purpose and the combination is strange.  If you see
  this sequence, investigate this by
  - Reading page 208 of Bryant/O'Hallaron which describes this in an
    "aside" , OR
  - Doing a little internet search which should yield similar
    information.
  Describe roughly why `rep ret' shows up here.


PROBLEM 2: Fizzbuzz, x86-64-Style
=================================

  The codepack contains the following source files related to this
  problem.
  - fizzbuzz.c : implementation of fizzbuzz in C
  - fuzzbuzz_asm.s : hand-coded assembly version of fizzbuzz

  Executables from these can be built using the Makefile just by typing
  `make'. Both programs do the same thing but illustrate a C vs Assembly
  rendition of the program.
  ,----
  | >> make
  | ...
  | gcc -o fizzbuzz -Og -g fizzbuzz.c
  | gcc -o fizzbuzz_asm -g fizzbuzz_asm.s
  | 
  | >> ./fizzbuzz
  | ./fizzbuzz <int>
  | 
  | >> ./fizzbuzz 20
  | 1
  | 2
  | Fizz
  | 4
  | Buzz
  | Fizz
  | 7
  | 8
  | Fizz
  | Buzz
  | 11
  | Fizz
  | 13
  | 14
  | Fizz Buzz
  | 16
  | 17
  | Fizz
  | 19
  | Buzz
  | >> ./fizzbuzz_asm 20
  | 1
  | 2
  | Fizz
  | 4
  | Buzz
  | Fizz
  | 7
  | 8
  | Fizz
  | Buzz
  | 11
  | Fizz
  | 13
  | 14
  | Fizz Buzz
  | 16
  | 17
  | Fizz
  | 19
  | Buzz
  `----


A
~

  The "Fizz Buzz" problem (<https://en.wikipedia.org/wiki/Fizz_buzz>) is
  a venerable programming interview screening question that all CS
  students should practice to ensure they do not get quickly
  disqualified during job interviews.  If you've not heard of it, follow
  the above link and practice solving it in your programming language of
  choice (perhaps C) to ensure you are acquainted with the problem.  As
  a quick reminder, the problem is:
  - For numbers I from 1 to N (inclusive) ...
  - If I is divisible by both 3 and 5, print "Fizz Buzz"
  - If I is only divisible by 3, print "Fizz"
  - If I is only divisible by 5, print "Buzz"
  - Otherwise print I

  Study the C program `fizzbuzz.c' to see how the problem is solved
  there.
  1. How is the first case of "divisible by 3 and 5" handled?
  2. How would you describe the structure of iteration / conditionals in
     the program?
  3. How does the program determine the maximum value to try for the
     calculation?


B
~

  Use the technique demonstrated in the first problem to convert
  `fizzbuzz.c' to assembly code using GCC.
  1. Write down the command used to do the conversion
  2. Write where the resulting assembly code is stored
  3. Examine the assembly code produced and state its relative length to
     the 28-line `fizzbuzz.c' implementation


C
~

  Examine the resulting assembly code that is produced by GCC in a text
  editor. Compare this to the hand-coded assembly version in
  `fizzbuzz_asm.s'. Contrast how the following items appear between
  these two.
  1. Labels for string constants like "Fizz"
  2. Labels for code positions like the different conditional cases, the
     beginning / ending of loop, etc.
  3. Presence of comments which start with the # character


D
~

  A common method for debugging programs is "print debugging" where
  print statements are added to observe the control flow and values
  present in a misbehaving program to gain insight on its
  behavior. Examine carefully the assembly instructions that are used to
  invoke the `printf()' function in `fizzbuzz_asm.s' for string
  constants and for printing an integer. What must be done to perform
  printf() calls at the assembly level and what implications does this
  have for "print debugging" in assembly?


Epilogue
~~~~~~~~

  The Debugger will be an essential tool trace the execution of assembly
  programs and understand their behavior as print debugging is
  intractable.

  Feel free to begin exploring the instructions presented in these
  programs and begin deepening your understanding of registers,
  instructions, control flow, and other aspects of x86-64.

Author: Chris Kauffman (profk@umd.edu)
Date: 2024-09-29 Sun 17:16