Assembly Language Standards
1 Introduction
Assembly Language code is difficult to understand without documentation. These Assembly Language Standards address
· function documentation headers
· documenting instructions
Accurate documentation is essential for others to understand code. Additionally, documentation can help explain more obscure functionality which the programmer might forget.
2 Function Documentation Header
Each subroutine (function) must be documented with a documentation header:
#******************* Name of Function *********************************
# Purpose:
# Explain what the function does including a brief overview of what it
# returns.
# Parameters: (if necessary)
# List each parameter on a separate line including data type name and
# description. Each item should begin with whether the parameter is passed
# in, out or both:
# I Passed in. Value isn’t modified by subroutine.
# O Passed out. Value is returned through this parameter.
# I/O Modified. Original value is used, but this subroutine modifies it.
# It should then show its offset from the %ebp, its data type, its name,
# and its meaning.
# Global Variables: (if necessary)
# variableName (staticOrExternal)describe its purpose
# Locals: (if necessary)
# Describe each automatic variable including its offset in the stack.
# Notes:
# Include any special assumptions. If global variables are referenced,
# reference them. Explain critical parts of the algorithm.
# Return value:
# List the values returned by the function. Do not list returned
# parameters. Remove if void.
Example:
#******************* hexDump *********************************
# Purpose:
# hexDump prints (to stdout) the address of the specified
# memory area being dumped, prints the contents of that
# memory area in printable characters (where possible) and
# hexadecimal, and returns the number of lines processed.
# Parameters:
# i 8(%ebp) char *psbBuffer this is the address of the memory
# area to be dumped. It may contain
# printable and binary characters.
# i 12(%ebp) int iBufferLength the length of the memory area in bytes.
# It must be less than 4800 bytes.
# i 16(%ebp) int iBytesPerLine the number of bytes to print per line.
# This value must be at least 10 and at
# most 40.
# Locals:
# -4(%ebp) int iLineOffset byte address of the print line
# -8(%ebp) int i subscript of the current character
# being printed
# -12(%ebp) int iNumChars the number of characters printed
# on a line. For most lines except
# the last one, it is the same as
# the iBytesPerLine.
# -16(%ebp) int iNullLineCnt count of the number of consecutive
# lines which are all zeroes
# -20(%ebp) char *pChar Pointer to a character within the
# buffer.
# Notes:
# 1. The dump output is broken into many lines based on
# iBufferLength and iBytesPerLine. For example, if
# the buffer is 200 bytes and the iBytesPerLine is
# 10 bytes/line, it will logically print 20 lines.
# 2. Each printed line includes its beginning offset (relative
# to 0).
# 3. If a line or multiple lines of output would have been
# all zeroes, it is suppressed. A message is printed
# stating how many lines were suppressed.
# 4. The output is written to stdout.
# Return value:
# -1 invalid parameter
# n number of lines printed including suppressed lines
3 Documenting Instructions
This is much more difficult to document than C programs. We have several considerations:
· Documentation on the instruction
· Documentation about register usage
· Explain conditionals
· Explain obscure instructions
3.1 Documentation on Instructions
Within the code, document what each instruction is doing based on your global, local, and parameter names. If a register (e.g., is holding one of those, the documentation should make that clear.
Example:
movl 16(%ebp), %edx # iBytesPerLine -> %edx
addl %edx, -4(%ebp) # Add iBytesPerLine to iLineOffset
3.2 Register Usage
Explain how registers are used. If a register is mostly used for a particular purpose, explain (other than calling convention registers like %ebp and %esp) what it does.
Example:
#
# Register Usage:
# %ebx for pChar (the pointer into the buffer)
# %ecx for i (subscript into the buffer)
#
3.3 Conditionals
Provide comments which explain what is happening with conditionals. For an if-then-else, document the true and false (else) parts.
Example:
#
# check iGradePt > 0
#
testl %eax, %eax # test iGradePt
jle .LFALSE4 # if iGradePt <= 0, jmp to .LFALSE4
#
# true: iGradePt > 0
#
addl $1, iPass # iPass++
jmp .LAFTER4 # Jump over false part
#
# false: iGradePt <= 0
#
.LFALSE4:
addl $1, iFail # iFail++
.LAFTER4:
3.4 Obscure Code
Explain obscure code.
Example:
# determine the address of the szStudentId[i]
# since each element is 20 bytes long, we need to multiply
# the subscript by 20.
# using leal (x,x,4) will multiply register x by 5
# using leal (,x,4) will multiply register x by 4
# Doing both of those leal instructions is x*20
#
# First multiply i (which is in %ebx) by 5
36 leal (%ebx,%ebx,4), %eax # i*5
# Now multiply that by 4 which effectively mult by 20
# and add the address of the beginning of the array
37 leal studentData+4(,%eax,4), %eax # (i*5) * 4