> 1111 - Invalid use of group function
The Art of Assembly Language Programming
You are visitor as of October 17, 1996.<br>The Art of Assembly Language Programming<br><br>Forward Why Would Anyone Learn This Stuff?<br>1 What's Wrong With Assembly Language<br>2 What's Right With Assembly Language?<br>3 Organization of This Text and Pedagogical Concerns<br>4 Obtaining Program Source Listings and Other Materials in This Text<br><br>Section One: Machine Organization<br><br>Art of Assembly Language: Chapter One<br>Chapter One - Data Representation<br>1.0 - Chapter Overview<br>1.1 - Numbering Systems<br>1.1.1 - A Review of the Decimal System<br>1.1.2 - The Binary Numbering System<br>1.1.3 - Binary Formats<br>1.2 - Data Organization<br>1.2.1 - Bits<br>1.2.2 - Nibbles<br>1.2.3 - Bytes<br>1.2.4 - Words<br>1.2.5 - Double Words<br>1.3 - The Hexadecimal Numbering System<br>1.4 - Arithmetic Operations on Binary and Hexadecimal Numbers<br>1.5 - Logical Operations on Bits<br>1.6 - Logical Operations on Binary Numbers and Bit Strings<br>1.7 - Signed and Unsigned Numbers<br>1.8 - Sign and Zero Extension<br>1.9 - Shifts and Rotates<br>1.10 - Bit Fields and Packed Data<br>1.11 - The ASCII Character Set<br><br>1.12 Summary<br>1.13 Laboratory Exercises<br>1.13.1 Installing the Software<br>1.13.2 Data Conversion Exercises<br>1.13.3 Logical Operations Exercises<br>1.13.4 Sign and Zero Extension Exercises<br>1.13.5 Packed Data Exercises<br>1.14 Questions<br>1.15 Programming Projects<br><br>Chapter Two - Boolean Algebra<br>2.0 - Chapter Overview<br>2.1 - Boolean Algebra<br>2.2 - Boolean Functions and Truth Tables<br>2.3 - Algebraic Manipulation of Boolean Expressions<br>2.4 - Canonical Forms<br>2.5 - Simplification of Boolean Functions<br>2.6 - What Does This Have To Do With Computers, Anyway?<br>2.6.1 - Correspondence Between Electronic Circuits and Boolean Functions<br>2.6.2 - Combinatorial Circuits<br>2.6.3 - Sequential and Clocked Logic<br>2.7 - Okay, What Does It Have To Do With Programming, Then?<br>2.8 - Generic Boolean Functions<br><br>2.9 Laboratory Exercises<br>2.9.1 Truth Tables and Logic Equations Exercises<br>2.9.2 Canonical Logic Equations Exercises<br>2.9.3 Optimization Exercises<br>2.9.4 Logic Evaluation Exercises<br>2.10 Programming Projects<br>2.11 Summary<br>2.12 Questions<br><br>Chapter Three - System Organization<br>3.0 - Chapter Overview<br>3.1 - The Basic System Components<br>3.1.1 - The System Bus<br>3.1.1.1 - The Data Bus<br>3.1.1.2 - The Address Bus<br>3.1.1.3 - The Control Bus<br>3.1.2 - The Memory Subsystem<br>3.1.3 - The I/O Subsystem<br>3.2 - System Timing<br>3.2.1 - The System Clock<br>3.2.2 - Memory Access and the System Clock<br>3.2.3 - Wait States<br>3.2.4 - Cache Memory<br>3.3 - The 886, 8286, 8486, and 8686 "Hypothetical" Processors<br>3.3.1 - CPU Registers<br>3.3.2 - The Arithmetic & Logical Unit<br>3.3.3 - The Bus Interface Unit<br>3.3.4 - The Control Unit and Instruction Sets<br>3.3.5 - The x86 Instruction Set<br>3.3.6 - Addressing Modes on the x86<br>3.3.7 - Encoding x86 Instructions<br>3.3.8 - Step-by-Step Instruction Execution<br>3.3.9 - The Differences Between the x86 Processors<br>3.3.10 - The 886 Processor<br>3.3.11 - The 8286 Processor<br>3.3.12 - The 8486 Processor<br>3.3.12.1 - The 8486 Pipeline<br>3.3.12.2 - Stalls in a Pipeline<br>3.3.12.3 - Cache, the Prefetch Queue, and the 8486<br>3.3.12.4 - Hazards on the 8486<br>3.3.13 - The 8686 Processor<br>3.4 - I/O (Input/Output)<br>3.5 - Interrupts and Polled I/O<br><br><br>3.6 Laboratory Exercises<br>3.6.1 The SIMx86 Program - Some Simple x86 Programs<br>3.6.2 Simple I/O-Mapped Input/Output Operations<br>3.6.3 Memory Mapped I/O<br>3.6.4 DMA Exercises<br>3.6.5 Interrupt Driven I/O Exercises<br>3.6.6 Machine Language Programming & Instruction Encoding Exercises<br>3.6.7 Self Modifying Code Exercises<br>3.7 Programming Projects<br>3.8 Summary<br>3.9 Questions<br><br>Chapter Four - Memory Layout and Access<br>4.0 - Chapter Overview<br>4.1 - The 80x86 CPUs:A Programmer's View<br>4.1.1 - 8086 General Purpose Registers<br>4.1.2 - 8086 Segment Registers<br>4.1.3 - 8086 Special Purpose Registers<br>4.1.4 - 80286 Registers<br>4.1.5 - 80386/80486 Registers<br>4.2 - 80x86 Physical Memory Organization<br>4.3 - Segments on the 80x86<br>4.4 - Normalized Addresses on the 80x86<br>4.5 - Segment Registers on the 80x86<br>4.6 - The 80x86 Addressing Modes<br>4.6.1 - 8086 Register Addressing Modes<br>4.6.2 - 8086 Memory Addressing Modes<br>4.6.2.1 - The Displacement Only Addressing Mode<br>4.6.2.2 - The Register Indirect Addressing Modes<br>4.6.2.3 - Indexed Addressing Modes<br>4.6.2.4 - Based Indexed Addressing Modes<br>4.6.2.5 - Based Indexed Plus Displacement Addressing Mode<br>4.6.2.6 - MASM Syntax for 8086 Memory Addressing Modes<br>4.6.2.7 - An Easy Way to Remember the 8086 Memory Addressing Modes<br>4.6.2.8 - Some Final Comments About 8086 Addressing Modes<br>4.6.3 - 80386 Register Addressing Modes<br>4.6.4 - 80386 Memory Addressing Modes<br>4.6.4.1 - Register Indirect Addressing Modes<br>4.6.4.2 - 80386 Indexed, Base/Indexed, and Base/Indexed/Disp Addressing Modes<br>4.6.4.3 - 80386 Scaled Indexed Addressing Modes<br>4.6.4.4 - Some Final Notes About the 80386 Memory Addressing Modes<br>4.7 - The 80x86 MOV Instruction<br>4.8 - Some Final Comments on the MOV Instructions<br><br>4.9 Laboratory Exercises<br>4.9.1 The UCR Standard Library for 80x86 Assembly Language Programmers<br>4.9.2 Editing Your Source Files<br>4.9.3 The SHELL.ASM File<br>4.9.4 Assembling Your Code with MASM<br>4.9.5 Debuggers and CodeView'<br>4.9.5.1 A Quick Look at CodeView<br>4.9.5.2 The Source Window<br>4.9.5.3 The Memory Window<br>4.9.5.4 The Register Window<br>4.9.5.5 The Command Window<br>4.9.5.6 The Output Menu Item<br>4.9.5.7 The CodeView Command Window<br>4.9.5.7.1 The Radix Command (N)<br>4.9.5.7.2 The Assemble Command<br>4.9.5.7.3 The Compare Memory Command<br>4.9.5.7.4 The Dump Memory Command<br>4.9.5.7.5 The Enter Command<br>4.9.5.7.6 The Fill Memory Command<br>4.9.5.7.7 The Move Memory Command<br>4.9.5.7.8 The Input Command<br>4.9.5.7.9 The Output Command<br>4.9.5.7.10 The Quit Command<br>4.9.5.7.11 The Register Command<br>4.9.5.7.12 The Unassemble Command<br>4.9.5.8 CodeView Function Keys<br>4.9.5.9 Some Comments on CodeView Addresses<br>4.9.5.10 A Wrap on CodeView<br>4.9.6 Laboratory Tasks<br>4.10 Programming Projects<br>4.11 Summary<br>4.12 Questions<br>Section Two: Basic Assembly Language<br><br>Chapter Five - Variables and Data Structures<br>5.0 - Chapter Overview<br>5.1 - Some Additional Instructions: LEA, LES, ADD, and MUL<br>5.2 - Declaring Variables in an Assembly Language Program<br>5.3 - Declaring and Accessing Scalar Variables<br>5.3.1 - Declaring and using BYTE Variables<br>5.3.2 - Declaring and using WORD Variables<br>5.3.3 - Declaring and using DWORD Variables<br>5.3.4 - Declaring and using FWORD, QWORD, and TBYTE Variables<br>5.3.5 - Declaring Floating Point Variables with REAL4, REAL8, and REAL10<br>5.4 - Creating Your Own Type Names with TYPEDEF<br>5.5 - Pointer Data Types<br>5.6 - Composite Data Types<br>5.6.1 - Arrays<br>5.6.1.1 - Declaring Arrays in Your Data Segment<br>5.6.1.2 - Accessing Elements of a Single Dimension Array<br>5.6.2 - Multidimensional Arrays<br>5.6.2.1 - Row Major Ordering<br>5.6.2.2 - Column Major Ordering<br>5.6.2.3 - Allocating Storage for Multidimensional Arrays<br>5.6.2.4 - Accessing Multidimensional Array Elements in Assembly Language<br>5.6.3 - Structures<br>5.6.4 - Arrays of Structures and Arrays/Structures as Structure Fields<br>5.6.5 - Pointers to Structures<br>5.7 - Sample Programs<br>5.7.1 - Simple Variable Declarations<br>5.7.2 - Using Pointer Variables<br>5.7.3 - Single Dimension Array Access<br>5.7.4 - Multidimensional Array Access<br>5.7.5 - Simple Structure Access<br>5.7.6 - Arrays of Structures<br>5.7.7 - Structures and Arrays as Fields of Another Structure<br>5.7.8 - Pointers to Structures and Arrays of Structure<br><br><br>5.8 Laboratory Exercises<br>5.9 Programming Projects<br>5.10 Summary<br>5.11 Questions<br><br>Chapter Six - The 80x86 Instruction Set<br>6.0 - Chapter Overview<br>6.1 - The Processor Status Register (Flags)<br>6.2 - Instruction Encodings<br>6.3 - Data Movement Instructions<br>6.3.1 - The MOV Instruction<br>6.3.2 - The XCHG Instruction<br>6.3.3 - The LDS, LES, LFS, LGS, and LSS Instructions<br>6.3.4 - The LEA Instruction<br>6.3.5 - The PUSH and POP Instructions<br>6.3.6 - The LAHF and SAHF Instructions<br>6.4 - Conversions<br>6.4.1 - The MOVZX, MOVSX, CBW, CWD, CWDE, and CDQ Instructions<br>6.4.2 - The BSWAP Instruction<br>6.4.3 - The XLAT Instruction<br>6.5 - Arithmetic Instructions<br>6.5.1 - The Addition Instructions: ADD, ADC, INC, XADD, AAA, and DAA<br>6.5.1.1 - The ADD and ADC Instructions<br>6.5.1.2 - The INC Instruction<br>6.5.1.3 - The XADD Instruction<br>6.5.1.4 - The AAA and DAA Instructions<br>6.5.2 - The Subtraction Instructions: SUB, SBB, DEC, AAS, and DAS<br>6.5.3 - The CMP Instruction<br>6.5.4 - The CMPXCHG, and CMPXCHG8B Instructions<br>6.5.5 - The NEG Instruction<br>6.5.6 - The Multiplication Instructions: MUL, IMUL, and AAM<br>6.5.7 - The Division Instructions: DIV, IDIV, and AAD<br>6.6 - Logical, Shift, Rotate and Bit Instructions<br>6.6.1 - The Logical Instructions: AND, OR, XOR, and NOT<br>6.6.2 - The Shift Instructions: SHL/SAL, SHR, SAR, SHLD, and SHRD<br>6.6.2.1 - SHL/SAL<br>6.6.2.2 - SAR<br>6.6.2.3 - SHR<br>6.6.2.4 - The SHLD and SHRD Instructions<br>6.6.3 - The Rotate Instructions: RCL, RCR, ROL, and ROR<br>6.6.3.1 - RCL<br>6.6.3.2 - RCR<br>6.6.3.3 - ROL<br>6.6.3.4 - ROR<br>6.6.4 - The Bit Operations<br>6.6.4.1 - TEST<br>6.6.4.2 - The Bit Test Instructions: BT, BTS, BTR, and BTC<br>6.6.4.3 - Bit Scanning: BSF and BSR<br>6.6.5 - The "Set on Condition" Instructions<br>6.7 - I/O Instructions<br>6.8 - String Instructions<br>6.9 - Program Flow Control Instructions<br>6.9.1 - Unconditional Jumps<br>6.9.2 - The CALL and RET Instructions<br>6.9.3 - The INT, INTO, BOUND, and IRET Instructions<br>6.9.4 - The Conditional Jump Instructions<br>6.9.5 - The JCXZ/JECXZ Instructions<br>6.9.6 - The LOOP Instruction<br>6.9.7 - The LOOPE/LOOPZ Instruction<br>6.9.8 - The LOOPNE/LOOPNZ Instruction<br>6.10 - Miscellaneous Instructions<br>6.11 - Sample Programs<br>6.11.1 - Simple Arithmetic I<br>6.11.2 - Simple Arithmetic II<br>6.11.3 - Logical Operations<br>6.11.4 - Shift and Rotate Operations<br>6.11.5 - Bit Operations and SETcc Instructions<br>6.11.6 - String Operations<br>6.11.7 - Conditional Jumps<br>6.11.8 - CALL and INT Instructions<br>6.11.9 - Conditional Jumps I<br>6.11.10 - Conditional Jump Instructions II<br><br><br>6.12 Laboratory Exercises<br>6.12.1 The IBM/L System<br>6.12.2 IBM/L Exercises<br>6.13 Programming Projects<br>6.14 Summary<br>6.15 Questions<br><br>Chapter Seven - The UCR Standard Library<br>7.0 - Chapter Overview<br>7.1 - An Introduction to the UCR Standard Library<br>7.1.1 - Memory Management Routines: MEMINIT, MALLOC, and FREE<br>7.1.2 - The Standard Input Routines: GETC, GETS, GETSM<br>7.1.3 - The Standard Output Routines: PUTC, PUTCR, PUTS, PUTH, PUTI, PRINT, and PRINTF<br>7.1.4 - Formatted Output Routines: Putisize, Putusize, Putlsize, and Putulsize<br>7.1.5 - Output Field Size Routines: Isize, Usize, and Lsize<br>7.1.6 - Conversion Routines: ATOx, and xTOA<br>7.1.7 - Routines that Test Characters for Set Membership<br>7.1.8 - Character Conversion Routines: ToUpper, ToLower<br>7.1.9 - Random Number Generation: Random, Randomize<br>7.1.10 - Constants, Macros, and other Miscellany<br>7.1.11 - Plus more!<br>7.2 - Sample Programs<br>7.2.1 - Stripped SHELL.ASM File<br>7.2.2 - Numeric I/O<br><br><br>7.3 Laboratory Exercises<br>7.3.1 Obtaining the UCR Standard Library<br>7.3.2 Unpacking the Standard Library<br>7.3.3 Using the Standard Library<br>7.3.4 The Standard Library Documentation Files<br>7.4 Programming Projects<br>7.5 Summary<br>7.6 Questions<br><br>Chapter Eight - MASM: Directives & Pseudo-Opcodes<br>8.0 - Chapter Overview<br>8.1 - Assembly Language Statements<br>8.2 - The Location Counter<br>8.3 - Symbols<br>8.4 - Literal Constants<br>8.4.1 - Integer Constants<br>8.4.2 - String Constants<br>8.4.3 - Real Constants<br>8.4.4 - Text Constants<br>8.5 - Declaring Manifest Constants Using Equates<br>8.6 - Processor Directives<br>8.7 - Procedures<br>8.8 - Segments<br>8.8.1 - Segment Names<br>8.8.2 - Segment Loading Order<br>8.8.3 - Segment Operands<br>8.8.3.1 - The ALIGN Type<br>8.8.3.2 - The COMBINE Type<br>8.8.4 - The CLASS Type<br>8.8.5 - The Read-only Operand<br>8.8.6 - The USE16, USE32, and FLAT Options<br>8.8.7 - Typical Segment Definitions<br>8.8.8 - Why You Would Want to Control the Loading Order<br>8.8.9 - Segment Prefixes<br>8.8.10 - Controlling Segments with the ASSUME Directive<br>8.8.11 - Combining Segments: The GROUP Directive<br>8.8.12 - Why Even Bother With Segments?<br>8.9 - The END Directive<br>8.10 - Variables<br>8.11 - Label Types<br>8.11.1 - How to Give a Symbol a Particular Type<br>8.11.2 - Label Values<br>8.11.3 - Type Conflicts<br>8.12 - Address Expressions<br>8.12.1 - Symbol Types and Addressing Modes<br>8.12.2 - Arithmetic and Logical Operators<br>8.12.3 - Coercion<br>8.12.4 - Type Operators<br>8.12.5 - Operator Precedence<br>8.13 - Conditional Assembly<br>8.13.1 - IF Directive<br>8.13.2 - IFE directive<br>8.13.3 - IFDEF and IFNDEF<br>8.13.4 - IFB, IFNB<br>8.13.5 - IFIDN, IFDIF, IFIDNI, and IFDIFI<br>8.14 - Macros<br>8.14.1 - Procedural Macros<br>8.14.2 - Macros vs. 80x86 Procedures<br>8.14.3 - The LOCAL Directive<br>8.14.4 - The EXITM Directive<br>8.14.5 - Macro Parameter Expansion and Macro Operators<br>8.14.6 - A Sample Macro to Implement For Loops<br>8.14.7 - Macro Functions<br>8.14.8 - Predefined Macros, Macro Functions, and Symbols<br>8.14.9 - Macros vs. Text Equates<br>8.14.10 - Macros: Good and Bad News<br>8.15 - Repeat Operations<br>8.16 - The FOR and FORC Macro Operations<br>8.17 - The WHILE Macro Operation<br>8.18 - Macro Parameters<br>8.19 - Controlling the Listing<br>8.19.1 - The ECHO and %OUT Directives<br>8.19.2 - The TITLE Directive<br>8.19.3 - The SUBTTL Directive<br>8.19.4 - The PAGE Directive<br>8.19.5 - The .LIST, .NOLIST, and .XLIST Directives<br>8.19.6 - Other Listing Directives<br>8.20 - Managing Large Programs<br>8.20.1 - The INCLUDE Directive<br>8.20.2 - The PUBLIC, EXTERN, and EXTRN Directives<br>8.20.3 - The EXTERNDEF Directive<br>8.21 - Make Files<br>8.22 - Sample Program<br>8.22.1 - EX8.MAK<br>8.22.2 - Matrix.A<br>8.22.3 - EX8.ASM<br>8.22.4 - GETI.ASM<br>8.22.5 - GetArray.ASM<br>8.22.6 - XProduct.ASM<br><br><br>8.23 Laboratory Exercises<br>8.23.1 Near vs. Far Procedures<br>8.23.2 Data Alignment Exercises<br>8.23.3 Equate Exercise<br>8.23.4 IFDEF Exercise<br>8.23.5 Make File Exercise<br>8.24 Programming Projects<br>8.25 Summary<br>8.26 Questions<br><br>Chapter Nine - Arithmetic and Logical Operations<br>9.0 - Chapter Overview<br>9.1 - Arithmetic Expressions<br>9.1.1 - Simple Assignments<br>9.1.2 - Simple Expressions<br>9.1.3 - Complex Expressions<br>9.1.4 - Commutative Operators<br>9.2 - Logical (Boolean) Expressions<br>9.3 - Multiprecision Operations<br>9.3.1 - Multiprecision Addition Operations<br>9.3.2 - Multiprecision Subtraction Operations<br>9.3.3 - Extended Precision Comparisons<br>9.3.4 - Extended Precision Multiplication<br>9.3.5 - Extended Precision Division<br>9.3.6 - Extended Precision NEG Operations<br>9.3.7 - Extended Precision AND Operations<br>9.3.8 - Extended Precision OR Operations<br>9.3.9 - Extended Precision XOR Operations<br>9.3.10 - Extended Precision NOT Operations<br>9.3.11 - Extended Precision Shift Operations<br>9.3.12 - Extended Precision Rotate Operations<br>9.4 - Operating on Different Sized Operands<br>9.5 - Machine and Arithmetic Idioms<br>9.5.1 - Multiplying Without MUL and IMUL<br>9.5.2 - Division Without DIV and IDIV<br>9.5.3 - Using AND to Compute Remainders<br>9.5.4 - Implementing Modulo-n Counters with AND<br>9.5.5 - Testing an Extended Precision Value for 0FFFF..FFh<br>9.5.6 - TEST Operations<br>9.5.7 - Testing Signs with the XOR Instruction<br>9.6 - Masking Operations<br>9.6.1 - Masking Operations with the AND Instruction<br>9.6.2 - Masking Operations with the OR Instruction<br>9.7 - Packing and Unpacking Data Types<br>9.8 - Tables<br>9.8.1 - Function Computation via Table Look Up<br>9.8.2 - Domain Conditioning<br>9.8.3 - Generating Tables<br>9.9 - Sample Programs<br>9.9.1 - Converting Arithmetic Expressions to Assembly Language<br>9.9.2 - Boolean Operations Example<br>9.9.3 - 64-bit Integer I/O<br>9.9.4 - Packing and Unpacking Date Data Types<br><br><br><br>9.10 Laboratory Exercises<br>9.10.1 Debugging Programs with CodeView<br>9.10.2 Debugging Strategies<br>9.10.2.1 Locating Infinite Loops<br>9.10.2.2 Incorrect Computations<br>9.10.2.3 Illegal Instructions/Infinite Loops Part II<br>9.10.3 Debug Exercise I: Using CodeView to Find Bugs in a Calculation<br>9.10.4 Software Delay Loop Exercises<br>9.11 Programming Projects<br>9.12 Summary<br>9.13 Questions<br><br>Chapter 10 - Control Structures<br>10.0 - Chapter Overview<br>10.1 - Introduction to Decisions<br>10.2 - IF..THEN..ELSE Sequences<br>10.3 - CASE Statements<br>10.4 - State Machines and Indirect Jumps<br>10.5 - Spaghetti Code<br>10.6 - Loops<br>10.6.1 - While Loops<br>10.6.2 - Repeat..Until Loops<br>10.6.3 - LOOP..ENDLOOP Loops<br>10.6.4 - FOR Loops<br>10.7 - Register Usage and Loops<br>10.8 - Performance Improvements<br>10.8.1 - Moving the Termination Condition to the End of a Loop<br>10.8.2 - Executing the Loop Backwards<br>10.8.3 - Loop Invariant Computations<br>10.8.4 - Unraveling Loops<br>10.8.5 - Induction Variables<br>10.8.6 - Other Performance Improvements<br>10.9 - Nested Statements<br>10.10 - Timing Delay Loops<br>10.11 - Sample Program<br><br><br><br>10.12 Laboratory Exercises<br>10.12.1 The Physics of Sound<br>10.12.2 The Fundamentals of Music<br>10.12.3 The Physics of Music<br>10.12.4 The 8253/8254 Timer Chip<br>10.12.5 Programming the Timer Chip to Produce Musical Tones<br>10.12.6 Putting it All Together<br>10.12.7 Amazing Grace Exercise<br>10.13 Programming Projects<br>10.14 Summary<br>10.15 Questions<br><br>Chapter Eleven - Procedures and Functions<br>11.0 - Chapter Overview<br>11.1 - Procedures<br>11.2 - Near and Far Procedures<br>11.2.1 - Forcing NEAR or FAR CALLs and Returns<br>11.2.2 - Nested Procedures<br>11.3 - Functions<br>11.4 - Saving the State of the Machine<br>11.5 - Parameters<br>11.5.1 - Pass by Value<br>11.5.2 - Pass by Reference<br>11.5.3 - Pass by Value-Returned<br>11.5.4 - Pass by Result<br>11.5.5 - Pass by Name<br>11.5.6 - Pass by Lazy-Evaluation<br>11.5.7 - Passing Parameters in Registers<br>11.5.8 - Passing Parameters in Global Variables<br>11.5.9 - Passing Parameters on the Stack<br>11.5.10 - Passing Parameters in the Code Stream<br>11.5.11 - Passing Parameters via a Parameter Block<br>11.6 - Function Results<br>11.6.1 - Returning Function Results in a Register<br>11.6.2 - Returning Function Results on the Stack<br>11.6.3 - Returning Function Results in Memory Locations<br>11.7 - Side Effects<br>11.8 - Local Variable Storage<br>11.9 - Recursion<br>11.10 - Sample Program<br><br>11.11 Laboratory Exercises<br>11.11.1 Ex11_1.cpp<br>11.11.2 Ex11_1.asm<br>11.11.3 EX11_1a.asm<br>11.12 Programming Projects<br>11.13 Summary<br>11.14 Questions<br><br>Section Three: Intermediate Level Assembly Language Programming<br><br>Chapter 12 - Procedures: Advanced Topics<br>12.0 - Chapter Overview<br>12.1 - Lexical Nesting, Static Links, and Displays<br>12.1.1 - Scope<br>12.1.2 - Unit Activation, Address Binding, and Variable Lifetime<br>12.1.3 - Static Links<br>12.1.4 - Accessing Non-Local Variables Using Static Links<br>12.1.5 - The Display<br>12.1.6 - The 80286 ENTER and LEAVE Instructions<br>12.2 - Passing Variables at Different Lex Levels as Parameters.<br>12.2.1 - Passing Parameters by Value in a Block Structured Language<br>12.2.2 - Passing Parameters by Reference, Result, and Value-Result in a Block Structured Language<br>12.2.3 - Passing Parameters by Name and Lazy-Evaluation in a Block Structured Language<br>12.3 - Passing Parameters as Parameters to Another Procedure<br>12.3.1 - Passing Reference Parameters to Other Procedures<br>12.3.2 - Passing Value-Result and Result Parameters as Parameters<br>12.3.3 - Passing Name Parameters to Other Procedures<br>12.3.4 - Passing Lazy Evaluation Parameters as Parameters<br>12.3.5 - Parameter Passing Summary<br>12.4 - Passing Procedures as Parameters<br>12.5 - Iterators<br>12.5.1 - Implementing Iterators Using In-Line Expansion<br>12.5.2 - Implementing Iterators with Resume Frames<br>12.6 - Sample Programs<br>12.6.1 - An Example of an Iterator<br>12.6.2 - Another Iterator Example<br><br><br>12.7 Laboratory Exercises<br>12.7.1 Iterator Exercise<br>12.7.2 The 80x86 Enter and Leave Instructions<br>12.7.3 Parameter Passing Exercises<br>12.8 Programming Projects<br>12.9 Summary<br>12.10 Questions<br><br>Chapter 13 - MS-DOS, PC-BIOS, and File I/O<br>13.0 - Chapter Overview<br>13.1 - The IBM PC BIOS<br>13.2 - An Introduction to the BIOS' Services<br>13.2.1 - INT 5- Print Screen<br>13.2.2 - INT 10h - Video Services<br>13.2.3 - INT 11h - Equipment Installed<br>13.2.4 - INT 12h - Memory Available<br>13.2.5 - INT 13h - Low Level Disk Services<br>13.2.6 - INT 14h - Serial I/O<br>13.2.6.1 - AH=0: Serial Port Initialization<br>13.2.6.2 - AH=1: Transmit a Character to the Serial Port<br>13.2.6.3 - AH=2: Receive a Character from the Serial Port<br>13.2.6.4 - AH=3: Serial Port Status<br>13.2.7 - INT 15h - Miscellaneous Services<br>13.2.8 - INT 16h - Keyboard Services<br>13.2.8.1 - AH=0: Read a Key From the Keyboard<br>13.2.8.2 - AH=1: See if a Key is Available at the Keyboard<br>13.2.8.3 - AH=2: Return Keyboard Shift Key Status<br>13.2.9 - INT 17h - Printer Services<br>13.2.9.1 - AH=0: Print a Character<br>13.2.9.2 - AH=1: Initialize Printer<br>13.2.9.3 - AH=2: Return Printer Status<br>13.2.10 - INT 18h - Run BASIC<br>13.2.11 - INT 19h - Reboot Computer<br>13.2.12 - INT 1Ah - Real Time Clock<br>13.2.12.1 - AH=0: Read the Real Time Clock<br>13.2.12.2 - AH=1: Setting the Real Time Clock<br>13.3 - An Introduction to MS-DOS'<br>13.3.1 - MS-DOS Calling Sequence<br>13.3.2 - MS-DOS Character Oriented Functions<br>13.3.3 - MS-DOS Drive Commands<br>13.3.4 - MS-DOS "Obsolete" Filing Calls<br>13.3.5 - MS-DOS Date and Time Functions<br>13.3.6 - MS-DOS Memory Management Functions<br>13.3.6.1 - Allocate Memory<br>13.3.6.2 - Deallocate Memory<br>13.3.6.3 - Modify Memory Allocation<br>13.3.6.4 - Advanced Memory Management Functions<br>13.3.7 - MS-DOS Process Control Functions<br>13.3.7.1 - Terminate Program Execution<br>13.3.7.2 - Terminate, but Stay Resident<br>13.3.7.3 - Execute a Program<br>13.3.8 - MS-DOS "New" Filing Calls<br>13.3.8.1 - Open File<br>13.3.8.2 - Create File<br>13.3.8.3 - Close File<br>13.3.8.4 - Read From a File<br>13.3.8.5 - Write to a File<br>13.3.8.6 - Seek (Move File Pointer)<br>13.3.8.7 - Set Disk Transfer Address (DTA)<br>13.3.8.8 - Find First File<br>13.3.8.9 - Find Next File<br>13.3.8.10 - Delete File<br>13.3.8.11 - Rename File<br>13.3.8.12 - Change/Get File Attributes<br>13.3.8.13 - Get/Set File Date and Time<br>13.3.8.14 - Other DOS Calls<br>13.3.9 - File I/O Examples<br>13.3.9.1 - Example #1: A Hex Dump Utility<br>13.3.9.2 - Example #2: Upper Case Conversion<br>13.3.10 - Blocked File I/O<br>13.3.11 - The Program Segment Prefix (PSP)<br>13.3.12 - Accessing Command Line Parameters<br>13.3.13 - ARGC and ARGV<br>13.4 - UCR Standard Library File I/O Routines<br>13.4.1 - Fopen<br>13.4.2 - Fcreate<br>13.4.3 - Fclose<br>13.4.4 - Fflush<br>13.4.5 - Fgetc<br>13.4.6 - Fread<br>13.4.7 - Fputc<br>13.4.8 - Fwrite<br>13.4.9 - Redirecting I/O Through the StdLib File I/O Routines<br>13.4.10 - A File I/O Example<br>13.5 - Sample Program<br><br>13.6 Laboratory Exercises<br>13.7 Programming Projects<br>13.8 Summary<br>13.9 Questions<br><br><br>Chapter 14 - Floating Point Arithmetic<br>14.0 - Chapter Overview<br>14.1 - The Mathematics of Floating Point Arithmetic<br>14.2 - IEEE Floating Point Formats<br>14.3 - The UCR Standard Library Floating Point Routines<br>14.3.1 - Load and Store Routines<br>14.3.2 - Integer/Floating Point Conversion<br>14.3.3 - Floating Point Arithmetic<br>14.3.4 - Float/Text Conversion and Printff<br>14.4 - The 80x87 Floating Point Coprocessors<br>14.4.1 - FPU Registers<br>14.4.1.1 - The FPU Data Registers<br>14.4.1.2 - The FPU Control Register<br>14.4.1.3 - The FPU Status Register<br>14.4.2 - FPU Data Types<br>14.4.3 - The FPU Instruction Set<br>14.4.4 - FPU Data Movement Instructions<br>14.4.4.1 - The FLD Instruction<br>14.4.4.2 - The FST and FSTP Instructions<br>14.4.4.3 - The FXCH Instruction<br>14.4.5 - Conversions<br>14.4.5.1 - The FILD Instruction<br>14.4.5.2 - The FIST and FISTP Instructions<br>14.4.5.3 - The FBLD and FBSTP Instructions<br>14.4.6 - Arithmetic Instructions<br>14.4.6.1 - The FADD and FADDP Instructions<br>14.4.6.2 - The FSUB, FSUBP, FSUBR, and FSUBRP Instructions<br>14.4.6.3 - The FMUL and FMULP Instructions<br>14.4.6.4 - The FDIV, FDIVP, FDIVR, and FDIVRP Instructions<br>14.4.6.5 - The FSQRT Instruction<br>14.4.6.6 - The FSCALE Instruction<br>14.4.6.7 - The FPREM and FPREM1 Instructions<br>14.4.6.8 - The FRNDINT Instruction<br>14.4.6.9 - The FXTRACT Instruction<br>14.4.6.10 - The FABS Instruction<br>14.4.6.11 - The FCHS Instruction<br>14.4.7 - Comparison Instructions<br>14.4.7.1 - The FCOM, FCOMP, and FCOMPP Instructions<br>14.4.7.2 - The FUCOM, FUCOMP, and FUCOMPP Instructions<br>14.4.7.3 - The FTST Instruction<br>14.4.7.4 - The FXAM Instruction<br>14.4.8 - Constant Instructions<br>14.4.9 - Transcendental Instructions<br>14.4.9.1 - The F2XM1 Instruction<br>14.4.9.2 - The FSIN, FCOS, and FSINCOS Instructions<br>14.4.9.3 - The FPTAN Instruction<br>14.4.9.4 - The FPATAN Instruction<br>14.4.9.5 - The FYL2X and FYL2XP1 Instructions<br>14.4.10 - Miscellaneous instructions<br>14.4.10.1 - The FINIT and FNINIT Instructions<br>14.4.10.2 - The FWAIT Instruction<br>14.4.10.3 - The FLDCW and FSTCW Instructions<br>14.4.10.4 - The FCLEX and FNCLEX Instructions<br>14.4.10.5 - The FLDENV, FSTENV, and FNSTENV Instructions<br>14.4.10.6 - The FSAVE, FNSAVE, and FRSTOR Instructions<br>14.4.10.7 - The FSTSW and FNSTSW Instructions<br>14.4.10.8 - The FINCSTP and FDECSTP Instructions<br>14.4.10.9 - The FNOP Instruction<br>14.4.10.10 - The FFREE Instruction<br>14.4.11 - Integer Operations<br>14.5 - Sample Program: Additional Trigonometric Functions<br><br>14.6 Laboratory Exercises<br>14.6.1 FPU vs StdLib Accuracy<br>14.7 Programming Projects<br>14.8 Summary<br>14.9 Questions<br><br>Chapter 15 - Strings and Character Sets<br>15.0 - Chapter Overview<br>15.1 - The 80x86 String Instructions<br>15.1.1 - How the String Instructions Operate<br>15.1.2 - The REP/REPE/REPZ and REPNZ/REPNE Prefixes<br>15.1.3 - The Direction Flag<br>15.1.4 - The MOVS Instruction<br>15.1.5 - The CMPS Instruction<br>15.1.6 - The SCAS Instruction<br>15.1.7 - The STOS Instruction<br>15.1.8 - The LODS Instruction<br>15.1.9 - Building Complex String Functions from LODS and STOS<br>15.1.10 - Prefixes and the String Instructions<br>15.2 - Character Strings<br>15.2.1 - Types of Strings<br>15.2.2 - String Assignment<br>15.2.3 - String Comparison<br>15.3 - Character String Functions<br>15.3.1 - Substr<br>15.3.2 - Index<br>15.3.3 - Repeat<br>15.3.4 - Insert<br>15.3.5 - Delete<br>15.3.6 - Concatenation<br>15.4 - String Functions in the UCR Standard Library<br>15.4.1 - StrBDel, StrBDelm<br>15.4.2 - Strcat, Strcatl, Strcatm, Strcatml<br>15.4.3 - Strchr<br>15.4.4 - Strcmp, Strcmpl, Stricmp, Stricmpl<br>15.4.5 - Strcpy, Strcpyl, Strdup, Strdupl<br>15.4.6 - Strdel, Strdelm<br>15.4.7 - Strins, Strinsl, Strinsm, Strinsml<br>15.4.8 - Strlen<br>15.4.9 - Strlwr, Strlwrm, Strupr, Struprm<br>15.4.10 - Strrev, Strrevm<br>15.4.11 - Strset, Strsetm<br>15.4.12 - Strspan, Strspanl, Strcspan, Strcspanl<br>15.4.13 - Strstr, Strstrl<br>15.4.14 - Strtrim, Strtrimm<br>15.4.15 - Other String Routines in the UCR Standard Library<br>15.5 - The Character Set Routines in the UCR Standard Library<br>15.6 - Using the String Instructions on Other Data Types<br>15.6.1 - Multi-precision Integer Strings<br>15.6.2 - Dealing with Whole Arrays and Records<br>15.7 - Sample Programs<br>15.7.1 - Find.asm<br>15.7.2 - StrDemo.asm<br>15.7.3 - Fcmp.asm<br><br><br><br>15.8 Laboratory Exercises<br>15.8.1 MOVS Performance Exercise #1<br>15.8.2 MOVS Performance Exercise #2<br>15.8.3 Memory Performance Exercise<br>15.8.4 The Performance of Length-Prefixed vs. Zero-Terminated Strings<br>15.9 Programming Projects<br>15.10 Summary<br>15.11 Questions<br><br>Chapter 16 - Pattern Matching<br>16.1 - An Introduction to Formal Language (Automata) Theory<br>16.1.1 - Machines vs. Languages<br>16.1.2 - Regular Languages<br>16.1.2.1 - Regular Expressions<br>16.1.2.2 - Nondeterministic Finite State Automata (NFAs)<br>16.1.2.3 - Converting Regular Expressions to NFAs<br>16.1.2.4 - Converting an NFA to Assembly Language<br>16.1.2.5 - Deterministic Finite State Automata (DFAs)<br>16.1.2.6 - Converting a DFA to Assembly Language<br>16.1.3 - Context Free Languages<br>16.1.4 - Eliminating Left Recursion and Left Factoring CFGs<br>16.1.5 - Converting REs to CFGs<br>16.1.6 - Converting CFGs to Assembly Language<br>16.1.7 - Some Final Comments on CFGs<br>16.1.8 - Beyond Context Free Languages<br>16.2 - The UCR Standard Library Pattern Matching Routines<br>16.3 - The Standard Library Pattern Matching Functions<br>16.3.1 - Spancset<br>16.3.2 - Brkcset<br>16.3.3 - Anycset<br>16.3.4 - Notanycset<br>16.3.5 - MatchStr<br>16.3.6 - MatchiStr<br>16.3.7 - MatchToStr<br>16.3.8 - MatchChar<br>16.3.9 - MatchToChar<br>16.3.10 - MatchChars<br>16.3.11 - MatchToPat<br>16.3.12 - EOS<br>16.3.13 - ARB<br>16.3.14 - ARBNUM<br>16.3.15 - Skip<br>16.3.16 - Pos<br>16.3.17 - RPos<br>16.3.18 - GotoPos<br>16.3.19 - RGotoPos<br>16.3.20 - SL_Match2<br>16.4 - Designing Your Own Pattern Matching Routines<br>16.5 - Extracting Substrings from Matched Patterns<br>16.6 - Semantic Rules and Actions<br>16.7 - Constructing Patterns for the MATCH Routine<br>16.8 - Some Sample Pattern Matching Applications<br>16.8.1 - Converting Written Numbers to Integers<br>16.8.2 - Processing Dates<br>16.8.3 - Evaluating Arithmetic Expressions<br>16.8.4 - A Tiny Assembler<br>16.8.5 - The "MADVENTURE" Game<br>16.9 - Laboratory Exercises<br>16.9.1 - Checking for Stack Overflow (Infinite Loops)<br>16.9.2 - Printing Diagnostic Messages from a Pattern<br><br><br><br>16.10 Programming Projects<br>16.11 Summary<br>16.12 Questions<br><br>Section Four: Advanced Assembly Language Programming<br><br>Chapter 17 - Interrupts, Traps, and Exceptions<br>17.1 - 80x86 Interrupt Structure and Interrupt Service Routines (ISRs)<br>17.2 - Traps<br>17.3 - Exceptions<br>17.3.1 - Divide Error Exception (INT 0)<br>17.3.2 - Single Step (Trace) Exception (INT 1)<br>17.3.3 - Breakpoint Exception (INT 3)<br>17.3.4 - Overflow Exception (INT 4/INTO)<br>17.3.5 - Bounds Exception (INT 5/BOUND)<br>17.3.6 - Invalid Opcode Exception (INT 6)<br>17.3.7 - Coprocessor Not Available (INT 7)<br>17.4 - Hardware Interrupts<br>17.4.1 - The 8259A Programmable Interrupt Controller (PIC)<br>17.4.2 - The Timer Interrupt (INT 8)<br>17.4.3 - The Keyboard Interrupt (INT 9)<br>17.4.4 - The Serial Port Interrupts (INT 0Bh and INT 0Ch)<br>17.4.5 - The Parallel Port Interrupts (INT 0Dh and INT 0Fh)<br>17.4.6 - The Diskette and Hard Drive Interrupts (INT 0Eh and INT 76h)<br>17.4.7 - The Real-Time Clock Interrupt (INT 70h)<br>17.4.8 - The FPU Interrupt (INT 75h)<br>17.4.9 - Nonmaskable Interrupts (INT 2)<br>17.4.10 - Other Interrupts<br>17.5 - Chaining Interrupt Service Routines<br>17.6 - Reentrancy Problems<br>17.7 - The Efficiency of an Interrupt Driven System<br>17.7.1 - Interrupt Driven I/O vs. Polling<br>17.7.2 - Interrupt Service Time<br>17.7.3 - Interrupt Latency<br>17.7.4 - Prioritized Interrupts<br>17.8 - Debugging ISRs<br><br><br><br>17.9 Summary<br><br>Chapter 18 - Resident Programs<br>18.1 - DOS Memory Usage and TSRs<br>18.2 - Active vs. Passive TSRs<br>18.3 - Reentrancy<br>18.3.1 - Reentrancy Problems with DOS<br>18.3.2 - Reentrancy Problems with BIOS<br>18.3.3 - Reentrancy Problems with Other Code<br>18.4 - The Multiplex Interrupt (INT 2Fh)<br>18.5 - Installing a TSR<br>18.6 - Removing a TSR<br>18.7 - Other DOS Related Issues<br>18.8 - A Keyboard Monitor TSR<br>18.9 - Semiresident Programs<br><br><br>18.10 Summary<br><br>Chapter 19 - Processes, Coroutines, and Concurrency<br>19.1 - DOS Processes<br>19.1.1 - Child Processes in DOS<br>19.1.1.1 - Load and Execute<br>19.1.1.2 - Load Program<br>19.1.1.3 - Loading Overlays<br>19.1.1.4 - Terminating a Process<br>19.1.1.5 - Obtaining the Child Process Return Code<br>19.1.2 - Exception Handling in DOS: The Break Handler<br>19.1.3 - Exception Handling in DOS: The Critical Error Handler<br>19.1.4 - Exception Handling in DOS: Traps<br>19.1.5 - Redirection of I/O for Child Processes<br>19.2 - Shared Memory<br>19.2.1 - Static Shared Memory<br>19.2.2 - Dynamic Shared Memory<br>19.3 - Coroutines<br>19.3.1 - AMAZE.ASM<br>19.3.2 - 32-bit Coroutines<br>19.4 - Multitasking<br>19.4.1 - Lightweight and HeavyWeight Processes<br>19.4.2 - The UCR Standard Library Processes Package<br>19.4.3 - Problems with Multitasking<br>19.4.4 - A Sample Program with Threads<br>19.5 - Synchronization<br>19.5.1 - Atomic Operations, Test & Set, and Busy-Waiting<br>19.5.2 - Semaphores<br>19.5.3 - The UCR Standard Library Semaphore Support<br>19.5.4 - Using Semaphores to Protect Critical Regions<br>19.5.5 - Using Semaphores for Barrier Synchronization<br>19.6 - Deadlock<br><br><br><br>19.7 Summary<br><br>Section Five: The PC's I/O Ports<br><br>Chapter 20 - The PC Keyboard<br>20.1 - Keyboard Basics<br>20.2 - The Keyboard Hardware Interface<br>20.3 - The Keyboard DOS Interface<br>20.4 - The Keyboard BIOS Interface<br>20.5 - The Keyboard Interrupt Service Routine<br>20.6 - Patching into the INT 9 Interrupt Service Routine<br>20.7 - Simulating Keystrokes<br>20.7.1 - Stuffing Characters in the Type Ahead Buffer<br>20.7.2 - Using the 80x86 Trace Flag to Simulate IN AL, 60H Instructions<br>20.7.3 - Using the 8042 Microcontroller to Simulate Keystrokes<br><br><br>20.8 Summary<br><br>Chapter 21 - The PC Parallel Ports<br>21.1 - Basic Parallel Port Information<br>21.2 - The Parallel Port Hardware<br>21.3 - Controlling a Printer Through the Parallel Port<br>21.3.1 - Printing via DOS<br>21.3.2 - Printing via BIOS<br>21.3.3 - An INT 17h Interrupt Service Routine<br>21.4 - Inter-Computer Communications on the Parallel Port<br><br><br><br>21.5 Summary<br><br>Chapter 22 - The PC Serial Ports<br>22.1 - The 8250 Serial Communications Chip<br>22.1.1 - The Data Register (Transmit/Receive Register)<br>22.1.2 - The Interrupt Enable Register (IER)<br>22.1.3 - The Baud Rate Divisor<br>22.1.4 - The Interrupt Identification Register (IIR)<br>22.1.5 - The Line Control Register<br>22.1.6 - The Modem Control Register<br>22.1.7 - The Line Status Register (LSR)<br>22.1.8 - The Modem Status Register (MSR)<br>22.1.9 - The Auxiliary Input Register<br>22.2 - The UCR Standard Library Serial Communications Support Routines<br>22.3 - Programming the 8250 (Examples from the Standard Library)<br><br>22.4 Summary<br><br>Chapter 23 - The PC Video Display<br>23.1 - Memory Mapped Video<br>23.2 - The Video Attribute Byte<br>23.3 - Programming the Text Display<br><br><br>23.4 Summary<br><br>Chapter 24 - The PC Game Adapter<br>24.1 - Typical Game Devices<br>24.2 - The Game Adapter Hardware<br>24.3 - Using BIOS' Game I/O Functions<br>24.4 - Writing Your Own Game I/O Routines<br>24.5 - The Standard Game Device Interface (SGDI)<br>24.5.1 - Application Programmer's Interface (API)<br>24.5.2 - Read4Sw<br>24.5.3 - Read4Pots:<br>24.5.4 - ReadPot<br>24.5.5 - Read4:<br>24.5.6 - CalibratePot<br>24.5.7 - TestPotCalibration<br>24.5.8 - ReadRaw<br>24.5.9 - ReadSwitch<br>24.5.10 - Read16Sw<br>24.5.11 - Remove<br>24.5.12 - TestPresence<br>24.5.13 - An SGDI Driver for the Standard Game Adapter Card<br>24.6 - An SGDI Driver for the CH Products' Flight Stick Pro'<br>24.7 - Patching Existing Games<br><br><br><br>24.8 Summary<br><br>Section Six: Optimization<br><br>25.1 - When to Optimize, When Not to Optimize<br>25.2 - How Do You Find the Slow Code in Your Programs?<br>25.3 - Is Optimization Necessary?<br>25.4 - The Three Types of Optimization<br>25.5 - Improving the Implementation of an Algorithm<br><br><br><br>25.6 Summary<br><br>Section Seven: Appendixes<br>Appendix A: ASCII/IBM Character Set<br>Appendix B: Annotated Bibliography<br>Appendix C: Keyboard Scan Codes<br>Appendix D: Instruction Set Reference<br>Section D1<br><br>Section D2<br><br>Section D3<br><br>Section D4<br><br>The Art of Assembly Language Programming - 30 SEP 1996<br><br>[Randall Hyde]<br>