- •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
XCHG Exchange Operands
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:
XCHG r8,r8 |
|
XCHG r8,m8 |
|
XCHG r16,r16 |
|
XCHG r16,m16 |
386+ |
XCHG r32,r32 |
|
XCHG r32,m32 |
386+ |
Examples:
XCHG AL,DH
XCHG BH,BYTE [SI]
XCHG SP,BP
XCHG DX,WORD [DI]
XCHG ESI,EDI
XCHG ECX,DWORD [EBP+38]
XCHG AX,BX ; Uses single-byte opcode
Notes:
XCHG exchanges the contents of its two operands. This is why there is no form of XCHG for identical operands; that is, XCHG AX,AX is not a legal form since exchanging a register with itself makes no logical sense.
Exchanging an operand with AX may be accomplished with a single-byte opcode, saving fetch time and code space. All good assemblers recognize these cases and optimize for them, but if you are hand-assembling INLINE statements for some high-level language, keep the single-byte special cases in mind.
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 |
|
|
XOR Exclusive 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:
XOR r8,r8 |
|
XOR m8,r8 |
|
XOR r8,m8 |
|
XOR r16,r16 |
|
XOR m16,r16 |
|
XOR r16,m16 |
386+ |
XOR r32,r32 |
|
XOR m32,r32 |
386+ |
XOR r32,m32 |
386+ |
XOR r8,i8 |
|
XOR m8,i8 |
|
XOR r16,i16 |
|
XOR m16,i16 |
386+ |
XOR r32,i32 |
|
XOR m32,i32 |
386+ |
XOR AL,i8 |
|
XOR AX,i16 |
386+ |
XOR EAX,i32 |
Examples:
XOR BX,DI |
;Uses single-byte opcode |
XOR AX,0FFFFH |
|
XOR AL,42H |
;Uses single-byte opcode |
XOR EBX,DWORD [EDI] |
|
XOR WORD [ES:BX],0B800H |
|
XOR WORD [BP+SI],DX |
|
Notes:
XOR performs the exclusive OR logical operation between its two operands. Once the operation is complete, the result replaces the destination operand. XOR is performed on a bit-by-bit basis, such that bit 0 of the source is XORed with bit 0 of the destination, bit 1 of the source is XORed with bit 1 of the destination, and so on. The XOR operation yields a 1 if the operands are different, and a 0 if the operands are the same. 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.
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
Appendix B: Segment Register Assumptions for
Real Mode Segmented Model
One reason the segmented modes are so awful is that there is a whole layer of assumptions to be remembered about which segments are used in which ways with which instructions, and what may be overridden with override prefixes. Here's a quick summary you can refer to if it ever gets all turned around in your head. Keep in mind that this applies only to real mode segmented model. In 32-bit protected mode (as in Linux), all the segments point to the same memory space, and thus you don't need to "mess with" segments and overrides.
Where allowed, segment assumptions may be overridden with the segment override prefixes. These are DS:, SS:, CS:, and ES:. Under NASM, they must be placed inside the memory reference brackets. (MASM and TASM place them outside the brackets.) Here's an example of such an override in action:
mov [ES:BX],AX
The assumptions are these:
1.When the offset is specified in BX, SI, or DI, the assumed segment register is DS.
2.When the offset is specified in SP, the assumed segment register is SS. This may not be overridden!
3.When the offset is specified in BP, the assumed segment register is SS.
4.For string instruction LODS, the assumed segment is DS and the assumed offset is SI. This may not be overridden!
5.For string instructions STOS and SCAS, the assumed segment is ES and the assumed offset is DI. This may not be overridden!
6.For string instruction MOVS, the source must be pointed to by DS:SI and the destination must be pointed to by ES:DI. This may not be overridden!
Appendix C: Web URLs for Assembly Programmers
Many assembly language books have gone out of print, but a great deal of assembly language information can be found on the Web. I include a number of sites that were current in early 2000 in the following list. Web addresses change or go bad on an aggravatingly regular basis, so if you can't find one of these sites, assume first that it's been moved, and only after some unsuccessful effort with the search engines, assume that the site is gone forever. (And for some things such as NASM, you can almost assume that it's been moved. Software as potent as NASM doesn't just disappear!)
The NASM home page: www.web-sites.co.uk/nasm/
The ALINK home page: http://alink.home.dhs.org/
The NASM-IDE home page: www.inglenook.co.uk/nasmide/
Linux assembly language page: http://lightning.voshod.com/asm/
Jan's Linux assembly page: http://bewoner.dma.be/JanW/eng.html
The 80x86 Assembly Pages: www.fys.ruu.nl/~faber/Amain.html
These are the best pages I've seen, and they've all been around for a while. You'll find links pages on some of them that may direct you to newer Web sites that don't exist as I write this. The Web is a living organism, and you never surf the same wave twice. Keep both eyes open, so you don't miss anything!