Log In
Or create an account ->
Imperial Library
Home
About
News
Upload
Forum
Help
Login/SignUp
Index
Write Great Code, Volume 2
Acknowledgments
Introduction
1. Thinking Low-Level, Writing High-Level
1.1 Misconceptions About Compiler Quality
1.2 Why Learning Assembly Language Is Still a Good Idea
1.3 Why Learning Assembly Language Isn’t Absolutely Necessary
1.4 Thinking Low-Level
1.4.1 Compilers Are Only as Good as the Source Code You Feed Them
1.4.2 Helping the Compiler Produce Better Machine Code
1.4.3 How to Think in Assembly While Writing HLL Code
1.5 Writing High-Level
1.6 Assumptions
1.7 Language-Neutral Approach
1.8 Characteristics of Great Code
1.9 The Environment for This Text
1.10 For More Information
2. Shouldn’t You Learn Assembly Language?
2.1 Roadblocks to Learning Assembly Language
2.2 Write Great Code, Volume 2, to the Rescue
2.3 High-Level Assemblers to the Rescue
2.4 The High-Level Assembler (HLA)
2.5 Thinking High-Level, Writing Low-Level
2.6 The Assembly Programming Paradigm (Thinking Low-Level)
2.7 The Art of Assembly Language and Other Resources
3. 80x86 Assembly for the HLL Programmer
3.1 Learning One Assembly Language Is Good, Learning More Is Better
3.2 80x86 Assembly Syntaxes
3.3 Basic 80x86 Architecture
3.3.1 Registers
3.3.2 80x86 General-Purpose Registers
3.3.3 The 80x86 EFLAGS Register
3.4 Literal Constants
3.4.1 Binary Literal Constants
3.4.1.1 Binary Literal Constants in HLA
3.4.1.2 Binary Literal Constants in Gas
3.4.1.3 Binary Literal Constants in MASM and TASM
3.4.2 Decimal Literal Constants
3.4.2.1 Decimal Literal Constants in HLA
3.4.2.2 Decimal Literal Constants in Gas, MASM, and TASM
3.4.3 Hexadecimal Literal Constants
3.4.3.1 Hexadecimal Literal Constants in HLA
3.4.3.2 Hexadecimal Literal Constants in Gas
3.4.3.3 Hexadecimal Literal Constants in MASM and TASM
3.4.4 Character and String Literal Constants
3.4.4.1 Character and String Literal Constants in HLA
3.4.4.2 Character and String Literal Constants in Gas
3.4.4.3 Character/String Literal Constants in MASM and TASM
3.4.5 Floating-Point Literal Constants
3.5 Manifest (Symbolic) Constants in Assembly Language
3.5.1 Manifest Constants in HLA
3.5.2 Manifest Constants in Gas
3.5.3 Manifest Constants in MASM and TASM
3.6 80x86 Addressing Modes
3.6.1 80x86 Register Addressing Modes
3.6.1.1 Register Access in HLA
3.6.1.2 Register Access in Gas
3.6.1.3 Register Access in MASM and TASM
3.6.2 Immediate Addressing Mode
3.6.3 Displacement-Only Memory Addressing Mode
3.6.4 Register Indirect Addressing Mode
3.6.4.1 Register Indirect Modes in HLA
3.6.4.2 Register Indirect Modes in MASM and TASM
3.6.4.3 Register Indirect Modes in Gas
3.6.5 Indexed Addressing Mode
3.6.5.1 Indexed Addressing Mode in HLA
3.6.5.2 Indexed Addressing Mode in MASM and TASM
3.6.5.3 Indexed Addressing Mode in Gas
3.6.6 Scaled-Indexed Addressing Modes
3.6.6.1 Scaled-Indexed Addressing in HLA
3.6.6.2 Scaled-Indexed Addressing in MASM and TASM
3.6.6.3 Scaled-Indexed Addressing in Gas
3.7 Declaring Data in Assembly Language
3.7.1 Data Declarations in HLA
3.7.2 Data Declarations in MASM and TASM
3.7.3 Data Declarations in Gas
3.7.3.1 Accessing Byte Variables in Assembly Language
3.8 Specifying Operand Sizes in Assembly Language
3.8.1 Type Coercion in HLA
3.8.2 Type Coercion in MASM and TASM
3.8.3 Type Coercion in Gas
3.9 The Minimal 80x86 Instruction Set
3.10 For More Information
4. PowerPC Assembly for the HLL Programmer
4.1 Learning One Assembly Language Is Good; More Is Better
4.2 Assembly Syntaxes
4.3 Basic PowerPC Architecture
4.3.1 General-Purpose Integer Registers
4.3.2 General-Purpose Floating-Point Registers
4.3.3 User-Mode-Accessible Special-Purpose Registers
4.3.3.1 Condition-Code Registers
4.3.3.2 Floating-Point Status and Control Register
4.3.3.3 XER Register
4.3.3.4 The LINK Register
4.3.3.5 The COUNT Register
4.3.3.6 The Time Base Registers (TBL and TBU)
4.4 Literal Constants
4.4.1 Binary Literal Constants
4.4.2 Decimal Literal Constants
4.4.3 Hexadecimal Literal Constants
4.4.4 Character and String Literal Constants
4.4.5 Floating-Point Literal Constants
4.5 Manifest (Symbolic) Constants in Assembly Language
4.6 PowerPC Addressing Modes
4.6.1 PowerPC Register Access
4.6.2 The Immediate Addressing Mode
4.6.3 PowerPC Memory Addressing Modes
4.6.3.1 Register Plus Displacement Addressing Mode
4.6.3.2 Register Plus Register (Indexed) Addressing Mode
4.7 Declaring Data in Assembly Language
4.8 Specifying Operand Sizes in Assembly Language
4.9 The Minimal Instruction Set
4.10 For More Information
5. Compiler Operation and Code Generation
5.1 File Types That Programming Languages Use
5.2 Programming Language Source Files
5.2.1 Tokenized Source Files
5.2.2 Specialized Source File Formats
5.3 Types of Computer Language Processors
5.3.1 Pure Interpreters
5.3.2 Interpreters
5.3.3 Compilers
5.3.4 Incremental Compilers
5.4 The Translation Process
5.4.1 Lexical Analysis and Tokens
5.4.2 Parsing (Syntax Analysis)
5.4.3 Intermediate Code Generation
5.4.4 Optimization
5.4.4.1 The Problem with Optimization
5.4.4.2 Optimization’s Effect on Compile Time
5.4.4.3 Basic Blocks, Reducible Code, and Optimization
5.4.4.4 Common Compiler Optimizations
5.4.4.5 Controlling Compiler Optimization
5.4.5 Comparing Different Compilers’ Optimizations
5.4.6 Native Code Generation
5.5 Compiler Output
5.5.1 Emitting HLL Code as Compiler Output
5.5.2 Emitting Assembly Language as Compiler Output
5.5.3 Emitting Object Files as Compiler Output
5.5.4 Emitting Executable Files as Compiler Output
5.6 Object File Formats
5.6.1 The COFF File Header
5.6.2 The COFF Optional Header
5.6.3 COFF Section Headers
5.6.4 COFF Sections
5.6.5 The Relocation Section
5.6.6 Debugging and Symbolic Information
5.6.7 Learning More About Object File Formats
5.7 Executable File Formats
5.7.1 Pages, Segments, and File Size
5.7.2 Internal Fragmentation
5.7.3 So Why Optimize for Space?
5.8 Data and Code Alignment in an Object File
5.8.1 Choosing a Section Alignment Size
5.8.2 Combining Sections
5.8.3 Controlling the Section Alignment
5.8.4 Section Alignment and Library Modules
5.9 Linkers and Their Effect on Code
5.10 For More Information
6. Tools for Analyzing Compiler Output
6.1 Background
6.2 Telling a Compiler to Produce Assembly Output
6.2.1 Assembly Output from GNU and Borland Compilers
6.2.2 Assembly Output from Visual C++
6.2.3 Example Assembly Language Output
6.2.3.1 Visual C++ Assembly Language Output
6.2.3.2 Borland C++ Assembly Language Output
6.2.3.3 Borland C++/Intel Backend Assembly Output
6.2.3.4 GCC Assembly Language Output (PowerPC)
6.2.3.5 GCC Assembly Language Output (80x86)
6.2.4 Analyzing Assembly Output from a Compiler
6.3 Using Object-Code Utilities to Analyze Compiler Output
6.3.1 The Microsoft dumpbin.exe Utility
6.3.1.1 The dumpbin.exe /all Command-Line Option
6.3.1.2 The dumpbin.exe /disasm Command-Line Option
6.3.1.3 The dumpbin.exe /headers Command-Line Option
6.3.1.4 The dumpbin.exe /imports Command-Line Option
6.3.1.5 The dumpbin.exe /relocations Command-Line Option
6.3.1.6 Other dumpbin.exe Command-Line Options
6.3.2 The FSF/GNU objdump.exe Utility
6.4 Using a Disassembler to Analyze Compiler Output
6.5 Using a Debugger to Analyze Compiler Output
6.5.1 Using an IDE’s Debugger
6.5.2 Using a Stand-Alone Debugger
6.6 Comparing Output from Two Compilations
6.6.1 Before-and-After Comparisons with diff
6.6.2 Manual Comparison
6.7 For More Information
7. Constants and High-Level Languages
7.1 Literal Constants and Program Efficiency
7.2 Literal Constants Versus Manifest Constants
7.3 Constant Expressions
7.4 Manifest Constants Versus Read-Only Memory Objects
7.5 Enumerated Types
7.6 Boolean Constants
7.7 Floating-Point Constants
7.8 String Constants
7.9 Composite Data Type Constants
7.10 For More Information
8. Variables in a High-Level Language
8.1 Runtime Memory Organization
8.1.1 The Code, Constant, and Read-Only Sections
8.1.2 The Static Variables Section
8.1.3 The BSS Section
8.1.4 The Stack Section
8.1.5 The Heap Section and Dynamic Memory Allocation
8.2 What Is a Variable?
8.2.1 Attributes
8.2.2 Binding
8.2.3 Static Objects
8.2.4 Dynamic Objects
8.2.5 Scope
8.2.6 Lifetime
8.2.7 So What Is a Variable?
8.3 Variable Storage
8.3.1 Static Binding and Static Variables
8.3.1.1 Binding at Language-Design Time
8.3.1.2 Binding at Compile Time
8.3.1.3 Binding at Link Time
8.3.1.4 Binding at Load Time
8.3.1.5 Static Variable Binding
8.3.2 Pseudo-Static Binding and Automatic Variables
8.3.3 Dynamic Binding and Dynamic Variables
8.4 Common Primitive Data Types
8.4.1 Integer Variables
8.4.2 Floating-Point/Real Variables
8.4.3 Character Variables
8.4.4 Boolean Variables
8.5 Variable Addresses and High-level Languages
8.5.1 Storage Allocation for Global and Static Variables
8.5.2 Using Automatic Variables to Reduce Offset Sizes
8.5.3 Storage Allocation for Intermediate Variables
8.5.4 Storage Allocation for Dynamic Variables and Pointers
8.5.5 Using Records/Structures to Reduce Instruction Offset Sizes
8.5.6 Register Variables
8.6 Variable Alignment in Memory
8.6.1 Records and Alignment
8.7 For More Information
9. Array Data Types
9.1 What Is an Array?
9.1.1 Array Declarations
9.1.1.1 Declaring Arrays in C, C++, and Java
9.1.1.2 Declaring Arrays in HLA
9.1.1.3 Declaring Arrays in Pascal, Delphi, and Kylix
9.1.1.4 Declaring Arrays with Noninteger Index Values
9.1.2 Array Representation in Memory
9.1.3 Accessing Elements of an Array
9.1.4 Padding Versus Packing
9.1.5 Multidimensional Arrays
9.1.5.1 Declaring Multidimensional Arrays
9.1.5.2 Mapping Multidimensional Array Elements to Memory
9.1.5.3 Row-Major Ordering
9.1.5.4 Column-Major Ordering
9.1.5.5 Accessing Elements of a Multidimensional Array
9.1.5.6 Emulating Column-Major or Row-Major Ordering
9.1.5.7 Improving Array Access Efficiency in Your Applications
9.1.6 Dynamic Versus Static Arrays
9.1.6.1 Single-Dimensional Pseudo-Dynamic Arrays
9.1.6.2 Multidimensional Pseudo-Dynamic Arrays
9.1.6.3 Pure Dynamic Arrays
9.2 For More Information
10. String Data Types
10.1 Character String Formats
10.1.1 Zero-Terminated Strings
10.1.1.1 Utilize C Standard Library String Functions
10.1.1.2 When Not to Use Standard Library Functions
10.1.1.3 Avoid Recomputing Data
10.1.1.4 Avoid Copying Data
10.1.1.5 A Final Comment on Zero-Terminated Strings
10.1.2 Length-Prefixed Strings
10.1.3 7-Bit Strings
10.1.4 HLA Strings
10.1.5 Descriptor-Based Strings
10.2 Static, Pseudo-Dynamic, and Dynamic Strings
10.2.1 Static Strings
10.2.2 Pseudo-Dynamic Strings
10.2.3 Dynamic Strings
10.3 Reference Counting for Strings
10.4 Delphi/Kylix Strings
10.5 Using Strings in a High-Level Language
10.6 Character Data in Strings
10.7 For More Information
11. Pointer Data Types
11.1 Defining and Demystifying Pointers
11.2 Pointer Implementation in High-Level Languages
11.3 Pointers and Dynamic Memory Allocation
11.4 Pointer Operations and Pointer Arithmetic
11.4.1 Adding an Integer to a Pointer
11.4.2 Subtracting an Integer from a Pointer
11.4.3 Subtracting a Pointer from a Pointer
11.4.4 Comparing Pointers
11.4.5 Logical AND/OR and Pointers
11.4.6 Other Operations with Pointers
11.5 A Simple Memory Allocator Example
11.6 Garbage Collection
11.7 The OS and Memory Allocation
11.8 Heap Memory Overhead
11.9 Common Pointer Problems
11.9.1 Using an Uninitialized Pointer
11.9.2 Using a Pointer That Contains an Illegal Value
11.9.3 Continuing to Use Storage After It Has Been Freed
11.9.4 Failing to Free Storage When Done with It
11.9.5 Accessing Indirect Data Using the Wrong Data Type
11.10 For More Information
12. Record Union, and Class Data Types
12.1 Records
12.1.1 Record Declarations in Various Languages
12.1.1.1 Records in Pascal/Delphi
12.1.1.2 Records in C/C++
12.1.1.3 Records in HLA
12.1.2 Instantiation of a Record
12.1.3 Initialization of Record Data at Compile Time
12.1.4 Memory Storage of Records
12.1.5 Using Records to Improve Memory Performance
12.1.6 Dynamic Record Types and Databases
12.2 Discriminant Unions
12.3 Union Declarations in Various Languages
12.3.1 Union Declarations in C/C++
12.3.2 Union Declarations in Pascal/Delphi/Kylix
12.3.3 Union Declarations in HLA
12.4 Memory Storage of Unions
12.5 Other Uses of Unions
12.6 Variant Types
12.7 Namespaces
12.8 Classes and Objects
12.8.1 Classes Versus Objects
12.8.2 Simple Class Declarations in C++
12.8.3 Virtual Method Tables
12.8.4 Sharing VMTs
12.8.5 Inheritance in Classes
12.8.6 Polymorphism in Classes
12.8.7 Classes, Objects, and Performance
12.9 For More Information
13. Arithmetic and Logical Expressions
13.1 Arithmetic Expressions and Computer Architecture
13.1.1 Stack-Based Machines
13.1.1.1 Basic Stack Machine Organization
13.1.1.2 Pushing Data onto a Stack
13.1.1.3 Popping Data from a Stack
13.1.1.4 Arithmetic Operations on a Stack Machine
13.1.1.5 Real-World Stack Machines
13.1.2 Accumulator-Based Machines
13.1.3 Register-Based Machines
13.1.4 Typical Forms of Arithmetic Expressions
13.1.5 Three-Address Architectures
13.1.6 Two-Address Architectures
13.1.7 Architectural Differences and Your Code
13.1.8 Handling Complex Expressions
13.2 Optimization of Arithmetic Statements
13.2.1 Constant Folding
13.2.2 Constant Propagation
13.2.3 Dead Code Elimination
13.2.4 Common Subexpression Elimination
13.2.5 Strength Reduction
13.2.6 Induction
12.2.7 Loop Invariants
13.2.8 Optimizers and Programmers
13.3 Side Effects in Arithmetic Expressions
13.4 Containing Side Effects: Sequence Points
13.5 Avoiding Problems Caused by Side Effects
13.6 Forcing a Particular Order of Evaluation
13.7 Short-Circuit Evaluation
13.7.1 Short-Circuit Evaluation and Boolean Expressions
13.7.2 Forcing Short-Circuit or Complete Boolean Evaluation
13.7.3 Efficiency Issues
13.8 The Relative Cost of Arithmetic Operations
13.9 For More Information
14. Control Structures and Programmatic Decisions
14.1 Control Structures Are Slower Than Computations!
14.2 Introduction to Low-Level Control Structures
14.3 The goto Statement
14.4 break, continue, next, return, and Other Limited Forms of the goto Statement
14.5 The if Statement
14.5.1 Improving the Efficiency of Certain if/else Statements
14.5.2 Forcing Complete Boolean Evaluation in an if Statement
14.5.3 Forcing Short-Circuit Boolean Evaluation in an if Statement
14.6 The switch/case Statement
14.6.1 Semantics of a switch/case Statement
14.6.2 Jump Tables Versus Chained Comparisons
14.6.3 Other Implementations of switch/case
14.6.4 Compiler Output for switch Statements
14.7 For More Information
15. Iterative Control Structures
15.1 The while Loop
15.1.1 Forcing Complete Boolean Evaluation in a while Loop
15.1.1.1 The Easy but Inefficient Approach
15.1.1.2 Using Inline Functions
15.1.1.3 Using Bitwise Logical Operations
15.1.1.4 Using Unstructured Code
15.1.2 Forcing Short-Circuit Boolean Evaluation in a while Loop
15.2 The repeat..until (do..until/do..while) Loop
15.2.1 Forcing Complete Boolean Evaluation in a repeat..until Loop
15.2.2 Forcing Short-Circuit Boolean Evaluation in a repeat..until Loop
15.3 The forever..endfor Loop
15.3.1 Forcing Complete Boolean Evaluation in a forever Loop
15.3.2 Forcing Short-Circuit Boolean Evaluation in a forever Loop
15.4 The Definite Loop (for Loops)
15.5 For More Information
16. Functions and Procedures
16.1 Simple Function and Procedure Calls
16.1.1 Storing the Return Address
16.1.2 Other Sources of Overhead
16.2 Leaf Functions and Procedures
16.3 Macros and Inline Functions
16.4 Passing Parameters to a Function or Procedure
16.5 Activation Records and the Stack
16.5.1 Composition of the Activation Record
16.5.2 Assigning Offsets to Local Variables
16.5.3 Associating Offsets with Parameters
16.5.3.1 The Pascal Calling Convention
16.5.3.2 The C Calling Convention
16.5.3.3 Passing Parameters in Registers
16.5.4 Accessing Parameters and Local Variables
16.6 Parameter-Passing Mechanisms
16.6.1 Pass-by-Value
16.6.2 Pass-by-Reference
16.7 Function Return Values
16.8 For More Information
A. Engineering Software
B. A Brief Comparison of the 80x86 and PowerPC CPU Families
A.1 Architectural Differences Between RISC and CISC
A.1.1 Work Accomplished per Instruction
A.1.2 Instruction Size
A.1.3 Clock Speed and Clocks per Instruction
A.1.4 Memory Access and Addressing Modes
A.1.5 Registers
A.1.6 Immediate (Constant) Operands
A.1.7 Stacks
A.2 Compiler and Application Binary Interface Issues
A.3 Writing Great Code for Both Architectures
C. Online Appendices
Online Appendix B
Online Appendix B
Index
Colophon
D. Updates
Copyright
← Prev
Back
Next →
← Prev
Back
Next →