- •Table of Contents
- •Foreword
- •Do Not Pass GO
- •Counting in Martian
- •Octal: How the Grinch Stole Eight and Nine
- •Hexadecimal: Solving the Digit Shortage
- •From Hex to Decimal and from Decimal to Hex
- •Arithmetic in Hex
- •Binary
- •Hexadecimal as Shorthand for Binary
- •Switches, Transistors, and Memory
- •The Shop Foreman and the Assembly Line
- •The Box That Follows a Plan
- •DOS and DOS files
- •Compilers and Assemblers
- •The Assembly Language Development Process
- •DEBUG and How to Use It
- •Chapter 5: NASM-IDE: A Place to Stand Give me a lever long enough, and a place to stand, and I will move the Earth.
- •NASM-IDE's Place to Stand
- •Using NASM-IDE's Tools
- •NASM-IDE's Editor in Detail
- •Other NASM-IDE Features
- •The Nature of Segments
- •16-Bit and 32-Bit Registers
- •The Three Major Assembly Programming Models
- •Reading and Changing Registers with DEBUG
- •Assembling and Executing Machine Instructions with DEBUG
- •Machine Instructions and Their Operands
- •Reading and Using an Assembly Language Reference
- •Rally Round the Flags, Boys!
- •Using Type Specifiers
- •The Bones of an Assembly Language Program
- •Assembling and Running EAT.ASM
- •One Program, Three Segments
- •Last In, First Out via the Stack
- •Using DOS Services through INT
- •Boxes within Boxes
- •Using BIOS Services
- •Building External Libraries of Procedures
- •Creating and Using Macros
- •Bits Is Bits (and Bytes Is Bits)
- •Shifting Bits
- •Flags, Tests, and Branches
- •Assembly Odds 'n Ends
- •The Notion of an Assembly Language String
- •REP STOSW, the Software Machine Gun
- •The Semiautomatic Weapon: STOSW without REP
- •Storing Data to Discontinuous Strings
- •Chapter 12: The Programmer's View of Linux Tools and Skills to Help You Write Assembly Code under a True 32-Bit OS
- •Prerequisites-Yukkh!
- •NASM for Linux
- •What's GNU?
- •The make Utility and Dependencies
- •Using the GNU Debugger
- •Your Work Strategy
- •Genuflecting to the C Culture
- •A Framework to Build On
- •The Perks of Protected Mode
- •Characters Out
- •Characters In
- •Be a Time Lord
- •Generating Random Numbers
- •Accessing Command-Line Arguments
- •Simple File I/O
- •Conclusion: Not the End, But Only the Beginning
- •Where to Now?
- •Stepping off Square One
- •Notes on the Instruction Set Reference
- •AAA Adjust AL after BCD Addition
- •ADC Arithmetic Addition with Carry
- •ADD Arithmetic Addition
- •AND Logical AND
- •BT Bit Test (386+)
- •CALL Call Procedure
- •CLC Clear Carry Flag (CF)
- •CLD Clear Direction Flag (DF)
- •CMP Arithmetic Comparison
- •DEC Decrement Operand
- •IMUL Signed Integer Multiplication
- •INC Increment Operand
- •INT Software Interrupt
- •IRET Return from Interrupt
- •J? Jump on Condition
- •JMP Unconditional Jump
- •LEA Load Effective Address
- •MOV Move (Copy) Right Operand into Left Operand
- •NOP No Operation
- •NOT Logical NOT (One's Complement)
- •OR Logical OR
- •POP Pop Top of Stack into Operand
- •POPA Pop All 16-Bit Registers (286+)
- •POPF Pop Top of Stack into Flags
- •POPFD Pop Top of Stack into EFlags (386+)
- •PUSH Push Operand onto Top of Stack
- •PUSHA Push All 16-Bit GP Registers (286+)
- •PUSHAD Push All 32-Bit GP Registers (386+)
- •PUSHF Push 16-Bit Flags onto Stack
- •PUSHFD Push 32-Bit EFlags onto Stack (386+)
- •RET Return from Procedure
- •ROL Rotate Left
- •ROR Rotate Right
- •SBB Arithmetic Subtraction with Borrow
- •SHL Shift Left
- •SHR Shift Right
- •STC Set Carry Flag (CF)
- •STD Set Direction Flag (DF)
- •STOS Store String
- •SUB Arithmetic Subtraction
- •XCHG Exchange Operands
- •XOR Exclusive Or
- •Appendix C: Web URLs for Assembly Programmers
- •Appendix D: Segment Register Assumptions
- •Appendix E: What's on the CD-ROM?
- •Index
- •List of Figures
- •List of Tables
Notes on the Instruction Set Reference
Instruction Operands
When an instruction takes two operands, the destination operand is the one on the left, and the source operand is the one on the right. In general, when a result is produced by an instruction, the result replaces the destination operand. For example, in this instruction:
ADD BX,SI
the BX register is added to the SI register, and the sum is then placed in the BX register, overwriting whatever was in BX before the addition.
Flag Results
Each instruction contains a flag summary that looks like this (the asterisks will vary from instruction to instruction):
O |
D |
I |
T |
S |
Z |
A |
P |
C |
OF: Overflow flag TF: Trap flag AF: Aux carry |
F |
F |
F |
F |
F |
F |
F |
F |
F |
DF: Direction flag SF: Sign flag PF: Parity flag |
** * * * * IF: Interrupt flag ZF: Zero flag CF: Carry flag
The nine flags are all represented here. An asterisk indicates that the instruction on that page affects that flag. If a flag is affected at all (that is, if it has an asterisk beneath it), it will be affected according to these rules:
OF Set if the result is too large to fit in the destination operand.
IF Set by the STI instruction; cleared by CLI.
TF For debuggers; not used in normal programming and may be ignored.
SF Set when the sign of the result forces the destination operand to become negative.
ZF Set if the result of an operation is zero. If the result is nonzero, ZF is cleared.
AF Auxiliary carry used for 4-bit BCD math. Set when an operation causes a carry out of a 4-bit BCD quantity.
PF Set if the number of 1 bits in the low byte of the result is even; cleared if the number of 1 bits in the low byte of the result is odd. Used in data communications applications but little else.
CF Set if the result of an add or shift operation carries out a bit beyond the destination operand; otherwise cleared. May be manually set by STC and manually cleared by CLC when CF must be in a known state before an operation begins.
Some instructions force certain flags to become undefined. When this is the case, it is noted under "Notes." Undefined means don't count on it being in any particular state.
AAA Adjust AL after BCD Addition
Flags affected:
O |
D |
I |
T |
S |
Z |
A |
P C |
OF: Overflow flag TF: Trap flag AF: Aux carry |
|||
F |
F |
F |
F |
F |
F |
F |
F F |
DF: Direction |
flag SF: Sign |
flag |
PF: Parity flag |
|
|
|
|
|
|
|
* * IF: Interrupt |
flag ZF: Zero |
flag |
CF: Carry flag |
Legal forms:
AAA
Examples:
AAA
Notes:
AAA makes an addition come out right in AL when what you're adding are BCD values rather than ordinary binary values. Note well that AAA does not perform the arithmetic itself, but is a postprocessor after ADD or ADC. The AL register is an implied operand and may not be explicitly stated-so make sure that the preceding ADD or ADC instruction leaves its results in AL!
A BCD digit is a byte with the high 4 bits set to 0, and the low 4 bits containing a digit from 0 to 9. AAA will yield garbage results if the preceding ADD or ADC acted upon one or both operands with values greater than 09.
After the addition of two legal BCD values, AAA will adjust a non-BCD result (that is, a result greater than 09 in AL) to a value between 0 and 9. This is called a decimal carry, since it is the carry of a BCD digit and not simply the carry of a binary bit.
For example, if ADD added 08 and 04 (both legal BCD values) to produce 0C in AL, AAA will take the 0C and adjust it to 02. The decimal carry goes to AH, not to the upper 4 bits of AL, which are always cleared to 0 by AAA.
If the preceding ADD or ADC resulted in a decimal carry (as in the preceding example), both CF and AF are set to 1 and AH is incremented by 1. Otherwise, AH is not incremented and CF and AF are cleared to 0.
This instruction is subtle. See the detailed discussion in Chapter 11.
r8 = AL AH BL BH CL CH DL DH sr = CS DS SS ES FS GS
m8 = 8-bit memory data
m32 = 32-bit memory data
i16 = 16-bit immediate data
d8 = 8-bit signed displacement
d32 = 32-bit unsigned displacement
r16 = AX BX CX DX BP SP SI DI
r32 = EAX EBX ECX EDX EBP ESP ESI E m16 = 16-bit memory data
i8 = 8-bit immediate data
i32 = 32-bit immediate data
d16 = 16-bit signed displacement
ADC Arithmetic Addition with Carry
Flags affected:
O |
D |
I |
T |
S |
Z |
A |
P |
C |
OF: |
Overflow flag TF: |
Trap |
flag |
AF: |
Aux carry |
F |
F |
F |
F |
F |
F |
F |
F |
F |
DF: |
Direction flag SF: |
Sign |
flag |
PF: |
Parity flag |
** * * * * IF: Interrupt flag ZF: Zero flag CF: Carry flag
Legal forms:
ADC r8,r8 |
|
ADC m8,r8 |
|
ADC r8,m8 |
|
ADC r16,r16 |
|
ADC m16,r16 |
|
ADC r16,m16 |
386+ |
ADC r32,r32 |
|
ADC m32,r32 |
386+ |
ADC r32,m32 |
386+ |
ADC r8,i8 |
|
ADC m8,i8 |
|
ADC r16,i16 |
|
ADC m16,i16 |
386+ |
ADC r32,i32 |
|
ADC m32,i32 |
386+ |
ADC r16,i8 |
|
ADC m16,i8 |
386+ |
ADC r32,i8 |
|
ADC m32,i8 |
386+ |
ADC AL,i8 |
|
ADC AX,i16 |
386+ |
ADC EAX,i32 |
Examples:
ADC BX,DI |
|
ADC EAX,5 |
;Uses single-byte opcode |
ADC AX,0FFFFH |
|
ADC AL,42H |
;Uses single-byte opcode |
ADC BP,17H |
|
ADC WORD [BX+SI+Inset],5 |
|
ADC WORD ES:[BX],0B800H |
|
Notes:
ADC adds the source operand and the Carry flag to the destination operand, and after the operation, the result replaces the destination operand. The add operation is an arithmetic add, and the carry allows multipleprecision additions across several registers or memory locations. (To add without taking the Carry flag into account, use the ADD instruction.) All affected flags are set according to the operation. Most importantly, if the result does not fit into the destination operand, the Carry flag is set to 1.
r8 |
= |
AL |
AH |
BL BH |
CL |
CH |
DL DH |
r16 |
= AX BX CX DX |
BP SP SI DI |
||||
sr = |
CS |
DS SS ES |
FS GS |
|
r32 |
= EAX EBX ECX |
EDX EBP ESP ESI E |
|||||||
m8 |
= |
= |
8-bit |
memory data |
|
m16 |
= |
16-bit |
memory data |
|||||
m32 |
|
32-bit |
memory |
data |
i8 = 8-bit immediate data |
|||||||||
i16 |
|
= |
16-bit |
immediate |
data |
i32 |
= |
32-bit |
immediate data |
d8 = 8-bit signed displacement |
d16 = 16-bit signed displacement |
d32 = 32-bit unsigned displacement