- •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
OR Logical OR
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:
OR r8,r8 |
|
OR m8,r8 |
|
OR r8,m8 |
|
OR r16,r16 |
|
OR m16,r16 |
|
OR r16,m16 |
386+ |
OR r32,r32 |
|
OR m32,r32 |
386+ |
OR r32,m32 |
386+ |
OR r8,i8 |
|
OR m8,i8 |
|
OR r16,i16 |
|
OR m16,i16 |
386+ |
OR r32,i32 |
|
OR m32,i32 |
386+ |
OR AL,i8 |
|
OR AX,i16 |
386+ |
OR EAX,i32 |
Examples:
OR EBX,EDI |
;Uses |
single-byte |
opcode |
||
OR |
AX,0FFFFH |
||||
OR |
AL,42H |
;Uses |
single-byte |
opcode |
|
OR |
WORD |
[ES:BX],0B800H |
|
|
|
OR |
WORD |
[BP+SI],DX |
|
|
|
Notes:
OR performs the OR logical operation between its two operands. Once the operation is complete, the result replaces the destination operand. OR is performed on a bit-by-bit basis, such that bit 0 of the source is ORed with bit 0 of the destination, bit 1 of the source is ORed with bit 1 of the destination, and so on. The OR operation yields a 1 if one of the operands is 1; and a 0 only if both operands are 0. Note that the operation makes the Auxiliary carry flag undefined. CF and OF are cleared to 0, and the other affected flags are set according to the operation's results.
Note You must use a size specifier (BYTE, WORD, DWORD) with memory data!
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 |
|
|
POP Pop Top of Stack into Operand
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 |
|
|
|
<none> |
IF: Interrupt |
flag ZF: Zero |
flag |
CF: Carry flag |
Legal forms:
POP r16
POP m16
POP r32
POP m32
POP sr
Examples:
POP WORD [BX]
POP EAX
POP DX
POP DWORD [EAX+ECX]
POP ES
Notes:
It is impossible to pop an 8-bit item from the stack. Also remember that the top of the stack is defined (in 16-bit modes) as the word at address SS:SP, and there's no way to override that using prefixes. In 32-bit modes, the top of the stack is the DWORD at [ESP]. There is a separate pair of instructions, PUSHF and POPF, for pushing and popping the Flags register.
All register forms have single-byte opcodes. NASM recognizes them and generates them automatically, even though there are larger forms in the CPU instruction decoding logic.
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
POPA Pop All 16-Bit Registers (286+)
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 |
|
|
|
<none> |
|
|
|
IF: Interrupt |
flag ZF: Zero |
flag |
CF: Carry flag |
Legal forms:
POPA
Examples:
POPA
Notes:
PUSHA pushes all 16-bit general-purpose registers onto the stack. This instruction is present on the 286 and later CPUs and is not available in the 8086/8088.
The 16-bit general-purpose registers are popped in this order:
DI, SI, BP, SP, BX, DX, CX, AX
There's one wrinkle here: The SP value popped off the stack is not popped back into SP! (That would be insane, since we're using SP to manage the stack as we pop values off of it.) The value in SP's position on the stack is simply discarded when instruction execution reaches it.
POPA is usually used in conjunction with PUSHA, but nothing guarantees this. If you pop garbage values off the stack into the general registers, well, interesting things (in the sense of the old Chinese curse) can and probably will happen.
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
POPF Pop Top of Stack into Flags
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:
POPF <none>
Examples:
POPF
Notes:
POPF pops the 16-bit word at the top of the stack into the Flags register. The top of the stack is defined as the word at SS:SP, and there is no way to override that with prefixes.
SP is incremented by two after the word comes off the stack. Remember that SP always points to either an empty stack or else real data. There is a separate pair of instructions, PUSH and POP, for pushing and popping other register data and memory data.
PUSHF and POPF are most used in writing 16-bit interrupt service routines, where you must be able to save and restore the environment, that is, all machine registers, to avoid disrupting machine operations while servicing the interrupt.
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