Assembly Advice
Practical Advice for Assembly Programming
- The .section directive specifies which “section” of the executable program assembled code or data will be placed in
Put things in the right place!
- Code goes in .text
- Read-only data such as string constants go in .rodata
- Uninitialized (zero-filled) variables and buffers go in .bss
- Use the .space directive to indicate how large these are
- Initialized (non-zero-filled) variables and buffers go in .data
- There are various directives such as .byte, .2byte, .4byte, etc. to specify initialized data values
Labels:
-
Labels are names representing addresses of code or data in memory
-
For functions and global variables, use appropriate names
- Functions and data exported to other modules must be marked with .globl
-
For control-flow targets within a function, use local labels
- These are labels which start with
.L(dot, followed by upper case L) - The assembler will not add these to the module’s symbol table
- Using “normal” labels for control flow makes debugging difficult because gdb thinks they are functions!
- These are labels which start with
Using GDB
-
You can debug assembly programs using gdb!
-
“Debugging by adding print statements” is much less practical for assembly programs than programs in a high level language
- Which isn’t to say it’s not possible or (occasionally) useful
-
Being able to use gdb confidently will greatly enhance your ability to develop working assembly language programs
-
Set breakpoints (break main, break myProg.S:123)
-
where: see current call stack
-
If you compiled your code with debugging symbols (i.e., using -g flag to gcc), next and step commands work as expected!
-
If code is compiled without debug symbols, it’s more difficult:
disassemble(or justdisas): display assembly code of currentfunctionstepi: step to next instructionnexti: step to next instruction (stepping overcallinstructions)
-
Set breakpoints (
break main, break myProg.S:123) -
where: see current call stack -
If you compiled your code with debugging symbols (i.e., using
-gflag togcc), next and step commands work as expected! -
If code is compiled without debug symbols, it’s more difficult:
disassemble(or just disas): display assembly code of current functionstepi: step to next instructionnexti: step to next instruction (stepping overcallinstructions)
-
Use
$prefix to refer to registers (e.g.,$rax,$edi, etc.) -
Use
printandcaststo C data types when inspecting data: -
Print 64 bit value
%rsppoints to: print *(unsigned long *)$rsp -
Print character string
%rdipoints to:print (char *)$rdi -
Print fourth element of array of int elements that
%r12points to:print ((int *)$r12)[3] -
Print contents of
%rcxis hexadecimal:print/x $rcx
Assembly Program Outline
.section .rodata
// read only strings
.section .bss
// zero-initialized global variables
.section .text
.global main
main:
subq $8, %rsp
.LinputLoop:
// do stuff
Linked from Computer System Fundamentals