You are previewing Professional Assembly Language.
O'Reilly logo
Professional Assembly Language

Book Description

  • Unlike high-level languages such as Java and C++, assembly language is much closer to the machine code that actually runs computers; it's used to create programs or modules that are very fast and efficient, as well as in hacking exploits and reverse engineering

  • Covering assembly language in the Pentium microprocessor environment, this code-intensive guide shows programmers how to create stand-alone assembly language programs as well as how to incorporate assembly language libraries or routines into existing high-level applications

  • Demonstrates how to manipulate data, incorporate advanced functions and libraries, and maximize application performance

  • Examples use C as a high-level language, Linux as the development environment, and GNU tools for assembling, compiling, linking, and debugging

  • Table of Contents

    1. Copyright
    2. About the Author
    3. Credits
    4. Acknowledgments
    5. Introduction
      1. Who This Book Is For
      2. What This Book Covers
      3. How This Book Is Structured
      4. What You Need to Use This Book
      5. Conventions
      6. Source Code
      7. Errata
      8. p2p.wrox.com
    6. 1. What Is Assembly Language?
      1. 1.1. Processor Instructions
        1. 1.1.1. Instruction code handling
        2. 1.1.2. Instruction code format
          1. 1.1.2.1. Opcode
          2. 1.1.2.2. Instruction prefix
          3. 1.1.2.3. Modifiers
            1. 1.1.2.3.1. The ModR/M byte
            2. 1.1.2.3.2. The SIB byte
            3. 1.1.2.3.3. The address displacement byte
          4. 1.1.2.4. Data element
      2. 1.2. High-Level Languages
        1. 1.2.1. Types of high-level languages
          1. 1.2.1.1. Compiled languages
          2. 1.2.1.2. Interpreted languages
          3. 1.2.1.3. Hybrid languages
        2. 1.2.2. High-level language features
          1. 1.2.2.1. Portability
          2. 1.2.2.2. Standardization
      3. 1.3. Assembly Language
        1. 1.3.1. Opcode mnemonics
        2. 1.3.2. Defining data
          1. 1.3.2.1. Using memory locations
          2. 1.3.2.2. Using the stack
        3. 1.3.3. Directives
      4. 1.4. Summary
    7. 2. The IA-32 Platform
      1. 2.1. Core Parts of an IA-32 Processor
        1. 2.1.1. Control unit
          1. 2.1.1.1. Instruction prefetch and decoding pipeline
          2. 2.1.1.2. Branch prediction unit
          3. 2.1.1.3. Out-of-order execution engine
          4. 2.1.1.4. Retirement unit
        2. 2.1.2. Execution unit
          1. 2.1.2.1. Low-latency integer execution unit
          2. 2.1.2.2. Complex-integer execution unit
          3. 2.1.2.3. Floating-point execution unit
        3. 2.1.3. Registers
          1. 2.1.3.1. General-purpose registers
          2. 2.1.3.2. Segment registers
          3. 2.1.3.3. Instruction pointer register
          4. 2.1.3.4. Control registers
        4. 2.1.4. Flags
          1. 2.1.4.1. Status flags
          2. 2.1.4.2. Control flags
          3. 2.1.4.3. System flags
      2. 2.2. Advanced IA-32 Features
        1. 2.2.1. The x87 floating-point unit
        2. 2.2.2. Multimedia extensions (MMX)
        3. 2.2.3. Streaming SIMD extensions (SSE)
        4. 2.2.4. Hyperthreading
      3. 2.3. The IA-32 Processor Family
        1. 2.3.1. Intel processors
          1. 2.3.1.1. The Pentium processor family
          2. 2.3.1.2. The P6 processor family
          3. 2.3.1.3. The Pentium 4 processor family
          4. 2.3.1.4. The Pentium Xeon processor family
        2. 2.3.2. Non-Intel processors
          1. 2.3.2.1. AMD processors
          2. 2.3.2.2. Cyrix processors
      4. 2.4. Summary
    8. 3. The Tools of the Trade
      1. 3.1. The Development Tools
        1. 3.1.1. The assembler
          1. 3.1.1.1. MASM
          2. 3.1.1.2. NASM
          3. 3.1.1.3. GAS
          4. 3.1.1.4. HLA
        2. 3.1.2. The linker
        3. 3.1.3. The debugger
        4. 3.1.4. The compiler
        5. 3.1.5. The object code disassembler
        6. 3.1.6. The profiler
      2. 3.2. The GNU Assembler
        1. 3.2.1. Installing the assembler
        2. 3.2.2. Using the assembler
        3. 3.2.3. A word about opcode syntax
      3. 3.3. The GNU Linker
      4. 3.4. The GNU Compiler
        1. 3.4.1. Downloading and installing gcc
        2. 3.4.2. Using gcc
      5. 3.5. The GNU Debugger Program
        1. 3.5.1. Downloading and installing gdb
        2. 3.5.2. Using gdb
      6. 3.6. The KDE Debugger
        1. 3.6.1. Downloading and installing kdbg
        2. 3.6.2. Using kdbg
      7. 3.7. The GNU Objdump Program
        1. 3.7.1. Using objdump
        2. 3.7.2. An objdump example
      8. 3.8. The GNU Profiler Program
        1. 3.8.1. Using the profiler
        2. 3.8.2. A profile example
      9. 3.9. A Complete Assembly Development System
        1. 3.9.1. The basics of Linux
        2. 3.9.2. Downloading and running MEPIS
        3. 3.9.3. Your new development system
      10. 3.10. Summary
    9. 4. A Sample Assembly Language Program
      1. 4.1. The Parts of a Program
        1. 4.1.1. Defining sections
        2. 4.1.2. Defining the starting point
      2. 4.2. Creating a Simple Program
        1. 4.2.1. The CPUID instruction
        2. 4.2.2. The sample program
        3. 4.2.3. Building the executable
        4. 4.2.4. Running the executable
        5. 4.2.5. Assembling using a compiler
      3. 4.3. Debugging the Program
        1. 4.3.1. Using gdb
          1. 4.3.1.1. Stepping through the program
          2. 4.3.1.2. Viewing the data
      4. 4.4. Using C Library Functions in Assembly
        1. 4.4.1. Using printf
        2. 4.4.2. Linking with C library functions
      5. 4.5. Summary
    10. 5. Moving Data
      1. 5.1. Defining Data Elements
        1. 5.1.1. The data section
        2. 5.1.2. Defining static symbols
        3. 5.1.3. The bss section
      2. 5.2. Moving Data Elements
        1. 5.2.1. The MOV instruction formats
        2. 5.2.2. Moving immediate data to registers and memory
        3. 5.2.3. Moving data between registers
        4. 5.2.4. Moving data between memory and registers
          1. 5.2.4.1. Moving data values from memory to a register
          2. 5.2.4.2. Moving data values from a register to memory
          3. 5.2.4.3. Using indexed memory locations
          4. 5.2.4.4. Using indirect addressing with registers
      3. 5.3. Conditional Move Instructions
        1. 5.3.1. The CMOV instructions
        2. 5.3.2. Using CMOV instructions
      4. 5.4. Exchanging Data
        1. 5.4.1. The data exchange instructions
          1. 5.4.1.1. XCHG
          2. 5.4.1.2. BSWAP
          3. 5.4.1.3. XADD
          4. 5.4.1.4. CMPXCHG
          5. 5.4.1.5. CMPXCHG8B
        2. 5.4.2. Using the data exchange instruction
      5. 5.5. The Stack
        1. 5.5.1. How the stack works
        2. 5.5.2. PUSHing and POPing data
        3. 5.5.3. PUSHing and POPing all the registers
        4. 5.5.4. Manually using the ESP and EBP registers
      6. 5.6. Optimizing Memory Access
      7. 5.7. Summary
    11. 6. Controlling Execution Flow
      1. 6.1. The Instruction Pointer
      2. 6.2. Unconditional Branches
        1. 6.2.1. Jumps
        2. 6.2.2. Calls
        3. 6.2.3. Interrupts
      3. 6.3. Conditional Branches
        1. 6.3.1. Conditional jump instructions
        2. 6.3.2. The compare instruction
        3. 6.3.3. Examples of using the flag bits
          1. 6.3.3.1. Using the Zero flag
          2. 6.3.3.2. Using the overflow flag
          3. 6.3.3.3. Using the parity flag
          4. 6.3.3.4. Using the sign flag
          5. 6.3.3.5. Using the carry flag
      4. 6.4. Loops
        1. 6.4.1. The loop instructions
        2. 6.4.2. A loop example
        3. 6.4.3. Preventing LOOP catastrophes
      5. 6.5. Duplicating High-Level Conditional Branches
        1. 6.5.1. if statements
        2. 6.5.2. for loops
      6. 6.6. Optimizing Branch Instructions
        1. 6.6.1. Branch prediction
          1. 6.6.1.1. Unconditional branches
          2. 6.6.1.2. Conditional branches
        2. 6.6.2. Optimizing tips
          1. 6.6.2.1. Eliminate branches
          2. 6.6.2.2. Code predictable branches first
          3. 6.6.2.3. Unroll loops
      7. 6.7. Summary
    12. 7. Using Numbers
      1. 7.1. Numeric Data Types
      2. 7.2. Integers
        1. 7.2.1. Standard integer sizes
        2. 7.2.2. Unsigned integers
        3. 7.2.3. Signed integers
          1. 7.2.3.1. Signed magnitude
          2. 7.2.3.2. One's complement
          3. 7.2.3.3. Two's complement
        4. 7.2.4. Using signed integers
        5. 7.2.5. Extending integers
          1. 7.2.5.1. Extending unsigned integers
          2. 7.2.5.2. Extending signed integers
        6. 7.2.6. Defining integers in GAS
      3. 7.3. SIMD Integers
        1. 7.3.1. MMX integers
        2. 7.3.2. Moving MMX integers
        3. 7.3.3. SSE integers
        4. 7.3.4. Moving SSE integers
      4. 7.4. Binary Coded Decimal
        1. 7.4.1. What is BCD?
        2. 7.4.2. FPU BCD values
        3. 7.4.3. Moving BCD values
      5. 7.5. Floating-Point Numbers
        1. 7.5.1. What are floating-point numbers?
          1. 7.5.1.1. Floating-point format
          2. 7.5.1.2. Binary floating-point format
        2. 7.5.2. Standard floating-point data types
        3. 7.5.3. IA-32 floating-point values
        4. 7.5.4. Defining floating-point values in GAS
        5. 7.5.5. Moving floating-point values
        6. 7.5.6. Using preset floating-point values
        7. 7.5.7. SSE floating-point data types
        8. 7.5.8. Moving SSE floating-point values
          1. 7.5.8.1. SSE floating-point values
          2. 7.5.8.2. SSE2 floating-point values
          3. 7.5.8.3. SSE3 instructions
      6. 7.6. Conversions
        1. 7.6.1. Conversion instructions
        2. 7.6.2. A conversion example
      7. 7.7. Summary
    13. 8. Basic Math Functions
      1. 8.1. Integer Arithmetic
        1. 8.1.1. Addition
          1. 8.1.1.1. The ADD instruction
          2. 8.1.1.2. Detecting a carry or overflow condition
          3. 8.1.1.3. The ADC instruction
          4. 8.1.1.4. An ADC example
        2. 8.1.2. Subtraction
          1. 8.1.2.1. The SUB instruction
          2. 8.1.2.2. Carry and overflow with subtraction
          3. 8.1.2.3. The SBB instruction
        3. 8.1.3. Incrementing and decrementing
        4. 8.1.4. Multiplication
          1. 8.1.4.1. Unsigned integer multiplication using MUL
          2. 8.1.4.2. A MUL instruction example
          3. 8.1.4.3. Signed integer multiplication using IMUL
          4. 8.1.4.4. An IMUL instruction example
          5. 8.1.4.5. Detecting overflows
        5. 8.1.5. Division
          1. 8.1.5.1. Unsigned division
          2. 8.1.5.2. Signed division
          3. 8.1.5.3. Detecting division errors
      2. 8.2. Shift Instructions
        1. 8.2.1. Multiply by shifting
        2. 8.2.2. Dividing by shifting
        3. 8.2.3. Rotating bits
      3. 8.3. Decimal Arithmetic
        1. 8.3.1. Unpacked BCD arithmetic
        2. 8.3.2. Packed BCD arithmetic
      4. 8.4. Logical Operations
        1. 8.4.1. Boolean logic
        2. 8.4.2. Bit testing
      5. 8.5. Summary
    14. 9. Advanced Math Functions
      1. 9.1. The FPU Environment
        1. 9.1.1. The FPU register stack
        2. 9.1.2. The FPU status, control, and tag registers
          1. 9.1.2.1. The status register
          2. 9.1.2.2. The control register
          3. 9.1.2.3. The tag register
        3. 9.1.3. Using the FPU stack
      2. 9.2. Basic Floating-Point Math
      3. 9.3. Advanced Floating-Point Math
        1. 9.3.1. Floating-point functions
        2. 9.3.2. Partial remainders
        3. 9.3.3. Trigonometric functions
          1. 9.3.3.1. The FSIN and FCOS instructions
          2. 9.3.3.2. The FSINCOS instruction
          3. 9.3.3.3. The FPTAN and FPATAN instructions
        4. 9.3.4. Logarithmic functions
      4. 9.4. Floating-Point Conditional Branches
        1. 9.4.1. The FCOM instruction family
        2. 9.4.2. The FCOMI instruction family
        3. 9.4.3. The FCMOV instruction family
      5. 9.5. Saving and Restoring the FPU State
        1. 9.5.1. Saving and restoring the FPU environment
        2. 9.5.2. Saving and restoring the FPU state
      6. 9.6. Waiting versus Nonwaiting Instructions
      7. 9.7. Optimizing Floating-Point Calculations
      8. 9.8. Summary
    15. 10. Working with Strings
      1. 10.1. Moving Strings
        1. 10.1.1. The MOVS instruction
        2. 10.1.2. The REP prefix
          1. 10.1.2.1. Moving a string byte by byte
          2. 10.1.2.2. Moving strings block by block
          3. 10.1.2.3. Moving large strings
          4. 10.1.2.4. Moving a string in reverse order
        3. 10.1.3. Other REP instructions
      2. 10.2. Storing and Loading Strings
        1. 10.2.1. The LODS instruction
        2. 10.2.2. The STOS instruction
        3. 10.2.3. Building your own string functions
      3. 10.3. Comparing Strings
        1. 10.3.1. The CMPS instruction
        2. 10.3.2. Using REP with CMPS
        3. 10.3.3. String inequality
      4. 10.4. Scanning Strings
        1. 10.4.1. The SCAS instruction
        2. 10.4.2. Scanning for multiple characters
        3. 10.4.3. Finding a string length
      5. 10.5. Summary
    16. 11. Using Functions
      1. 11.1. Defining Functions
      2. 11.2. Assembly Functions
        1. 11.2.1. Writing functions
          1. 11.2.1.1. Defining input values
          2. 11.2.1.2. Defining function processes
          3. 11.2.1.3. Defining output values
          4. 11.2.1.4. Creating the function
        2. 11.2.2. Accessing functions
        3. 11.2.3. Function placement
        4. 11.2.4. Using registers
        5. 11.2.5. Using global data
      3. 11.3. Passing Data Values in C Style
        1. 11.3.1. Revisiting the stack
        2. 11.3.2. Passing function parameters on the stack
        3. 11.3.3. Function prologue and epilogue
        4. 11.3.4. Defining local function data
        5. 11.3.5. Cleaning out the stack
        6. 11.3.6. An example
        7. 11.3.7. Watching the stack in action
      4. 11.4. Using Separate Function Files
        1. 11.4.1. Creating a separate function file
        2. 11.4.2. Creating the executable file
        3. 11.4.3. Debugging separate function files
      5. 11.5. Using Command-Line Parameters
        1. 11.5.1. The anatomy of a program
        2. 11.5.2. Analyzing the stack
        3. 11.5.3. Viewing command-line parameters
        4. 11.5.4. Viewing environment variables
        5. 11.5.5. An example using command-line parameters
      6. 11.6. Summary
    17. 12. Using Linux System Calls
      1. 12.1. The Linux Kernel
        1. 12.1.1. Parts of the kernel
          1. 12.1.1.1. Memory management
          2. 12.1.1.2. Device management
          3. 12.1.1.3. File system management
          4. 12.1.1.4. Process management
        2. 12.1.2. Linux kernel version
      2. 12.2. System Calls
        1. 12.2.1. Finding system calls
        2. 12.2.2. Finding system call definitions
        3. 12.2.3. Common system calls
      3. 12.3. Using System Calls
        1. 12.3.1. The system call format
          1. 12.3.1.1. System call values
          2. 12.3.1.2. System call input values
          3. 12.3.1.3. System call return value
      4. 12.4. Advanced System Call Return Values
        1. 12.4.1. The sysinfo system call
        2. 12.4.2. Using the return structure
        3. 12.4.3. Viewing the results
      5. 12.5. Tracing System Calls
        1. 12.5.1. The strace program
        2. 12.5.2. Advanced strace parameters
        3. 12.5.3. Watching program system calls
        4. 12.5.4. Attaching to a running program
      6. 12.6. System Calls versus C Libraries
        1. 12.6.1. The C libraries
        2. 12.6.2. Tracing C functions
        3. 12.6.3. Comparing system calls and C libraries
      7. 12.7. Summary
    18. 13. Using Inline Assembly
      1. 13.1. What Is Inline Assembly?
      2. 13.2. Basic Inline Assembly Code
        1. 13.2.1. The asm format
        2. 13.2.2. Using global C variables
        3. 13.2.3. Using the volatile modifier
        4. 13.2.4. Using an alternate keyword
      3. 13.3. Extended ASM
        1. 13.3.1. Extended ASM format
        2. 13.3.2. Specifying input and output values
        3. 13.3.3. Using registers
        4. 13.3.4. Using placeholders
        5. 13.3.5. Referencing placeholders
        6. 13.3.6. Alternative placeholders
        7. 13.3.7. Changed registers list
        8. 13.3.8. Using memory locations
        9. 13.3.9. Using floating-point values
        10. 13.3.10. Handling jumps
      4. 13.4. Using Inline Assembly Code
        1. 13.4.1. What are macros?
        2. 13.4.2. C macro functions
        3. 13.4.3. Creating inline assembly macro functions
      5. 13.5. Summary
    19. 14. Calling Assembly Libraries
      1. 14.1. Creating Assembly Functions
      2. 14.2. Compiling the C and Assembly Programs
        1. 14.2.1. Compiling assembly source code files
        2. 14.2.2. Using assembly object code files
        3. 14.2.3. The executable file
      3. 14.3. Using Assembly Functions in C Programs
        1. 14.3.1. Using integer return values
        2. 14.3.2. Using string return values
        3. 14.3.3. Using floating-point return values
        4. 14.3.4. Using multiple input values
        5. 14.3.5. Using mixed data type input values
          1. 14.3.5.1. Placing input values in the proper order
          2. 14.3.5.2. Reading input values in the proper order
      4. 14.4. Using Assembly Functions in C++ Programs
      5. 14.5. Creating Static Libraries
        1. 14.5.1. What is a static library?
        2. 14.5.2. The ar command
        3. 14.5.3. Creating a static library file
        4. 14.5.4. Compiling with static libraries
      6. 14.6. Using Shared Libraries
        1. 14.6.1. What are shared libraries?
        2. 14.6.2. Creating a shared library
        3. 14.6.3. Compiling with a shared library
        4. 14.6.4. Running programs that use shared libraries
          1. 14.6.4.1. The LD_LIBRARY_PATH environment variable
          2. 14.6.4.2. The /etc/ld.so.conf file
      7. 14.7. Debugging Assembly Functions
        1. 14.7.1. Debugging C programs
        2. 14.7.2. Debugging assembly functions
      8. 14.8. Summary
    20. 15. Optimizing Routines
      1. 15.1. Optimized Compiler Code
        1. 15.1.1. Compiler optimization level 1
        2. 15.1.2. Compiler optimization level 2
        3. 15.1.3. Compiler optimization level 3
      2. 15.2. Creating Optimized Code
        1. 15.2.1. Generating the assembly language code
        2. 15.2.2. Viewing optimized code
        3. 15.2.3. Recompiling the optimized code
      3. 15.3. Optimization Tricks
        1. 15.3.1. Optimizing calculations
          1. 15.3.1.1. Calculations without optimization
          2. 15.3.1.2. Viewing the optimized calculations
        2. 15.3.2. Optimizing variables
          1. 15.3.2.1. Using global and local variables without optimizing
          2. 15.3.2.2. Global and local variables with optimization
        3. 15.3.3. Optimizing loops
          1. 15.3.3.1. Normal for-next loop code
          2. 15.3.3.2. Viewing loop code
          3. 15.3.3.3. Optimizing the for-next loop
        4. 15.3.4. Optimizing conditional branches
          1. 15.3.4.1. Generic if-then code
          2. 15.3.4.2. Viewing if-then code
          3. 15.3.4.3. Optimized If-Then Code
        5. 15.3.5. Common subexpression elimination
          1. 15.3.5.1. A program example
          2. 15.3.5.2. Optimizing with cse
      4. 15.4. Summary
    21. 16. Using Files
      1. 16.1. The File-Handling Sequence
      2. 16.2. Opening and Closing Files
        1. 16.2.1. Access types
        2. 16.2.2. UNIX permissions
        3. 16.2.3. Open file code
        4. 16.2.4. Open error return codes
        5. 16.2.5. Closing files
      3. 16.3. Writing to Files
        1. 16.3.1. A simple write example
        2. 16.3.2. Changing file access modes
        3. 16.3.3. Handling file errors
      4. 16.4. Reading Files
        1. 16.4.1. A simple read example
        2. 16.4.2. A more complicated read example
      5. 16.5. Reading, Processing, and Writing Data
      6. 16.6. Memory-Mapped Files
        1. 16.6.1. What are memory-mapped files?
        2. 16.6.2. The mmap system call
        3. 16.6.3. mmap assembly language format
        4. 16.6.4. An mmap example
          1. 16.6.4.1. Parts of the program
          2. 16.6.4.2. The main program
          3. 16.6.4.3. Watching the program
      7. 16.7. Summary
    22. 17. Using Advanced IA-32 Features
      1. 17.1. A Brief Review of SIMD
        1. 17.1.1. MMX
        2. 17.1.2. SSE
        3. 17.1.3. SSE2
      2. 17.2. Detecting Supported SIMD Operations
        1. 17.2.1. Detecting support
        2. 17.2.2. SIMD feature program
      3. 17.3. Using MMX Instructions
        1. 17.3.1. Loading and retrieving packed integer values
        2. 17.3.2. Performing MMX operations
          1. 17.3.2.1. MMX addition and subtraction instructions
          2. 17.3.2.2. MMX multiplication instructions
          3. 17.3.2.3. MMX logical and shift instructions
          4. 17.3.2.4. MMX comparison instructions
      4. 17.4. Using SSE Instructions
        1. 17.4.1. Moving data
        2. 17.4.2. Processing data
          1. 17.4.2.1. Arithmetic instructions
          2. 17.4.2.2. Comparison instructions
          3. 17.4.2.3. SSE integer instructions
      5. 17.5. Using SSE2 Instructions
        1. 17.5.1. Moving data
        2. 17.5.2. Processing data
      6. 17.6. SSE3 Instructions
      7. 17.7. Summary