A P P E N D I X E S
for
A Guide to DEBUG
( The Microsoft® DEBUG.EXE
Program )
Copyright©2004, 2013 by Daniel B. Sedory
This
page may be freely copied for PERSONAL use ONLY !
( It may NOT be used for ANY other purpose UNLESS
you have
first contacted and received permission
from the author ! )
First, a quick review of how Binary and Hexadecimal numbers are related:
When the ones and zeros of four Binary bits are grouped together (from 0000 to 1111; often called a nibble), they can be represented by a single Hex digit (from 0 to F); both of which are used to count from 0 to 15 in Decimal.
Eight Binary bits (which allow for any Decimal value from 0 to 255) are represented by two Hex digits; for
example, the Binary number 10101010 is equal to AA in
Hexadecimal. Two-digit Hex numbers (or 8-bit Binary numbers) are called bytes. No matter how many digits a
number has in Binary or Hexadecimal, you can switch between the two by grouping and converting every four Binary bits
to one Hex digit or vice versa. The Hexadecimal equivalent of a 12-bit Binary must have 3 digits (e.g., 101010111100 = ABC hex), and the largest Decimal number that can be
represented by sixteen Binary bits (65,535) is equivalent to FFFF in Hex.
The four main (16-bit) registers of an 8086 CPU are called: The Accumulator (AX), Base (BX), Count (CX) and Data (DX)
Registers. Each of these registers has a High (H) and Low (L) 8-bit half which can store one Hexadecimal byte (1 byte
= 8 binary bits). Each of these high and low halves can be accessed separately by program code:
AX: |
|
Accumulator | ||||||||||||
BX: | Base Register | |||||||||||||
CX: | Count Register | |||||||||||||
DX: | Data Register | |||||||||||||
The other 16-bit ( two-byte ) registers of the 8086 CPU are:
| Stack Pointer |
|||||
|
Base Pointer |
|||||
|
Source Index |
|||||
|
Destination Index |
|
|
Code Segment |
||||
|
Data Segment | |||||
|
Stack Segment | |||||
|
Extra Segment |
|
|
Instruction Pointer |
The 8086 CPU uses a method I'll call the SEGMENT:
OFFSET scheme whenever it needs to access Memory locations or Jump from one 64kb Segment to another.
It does this by combining two 16-bit registers together to form a 20-bit Segment:Offset value ( which means it can
access over 1MB of Memory this way). For certain types of tasks, the registers are often grouped together in
the same way, but the programmer must still make sure that the CPU will use them as expected. Here are a couple tasks
which are set by the CPU itself:
CS : IP Next Instruction
SS : SP Stack Pointer
Two other sets which are often used together in
String operations
are: DS : SI Source Index
ES : DI Destination Index
The "FLAGS" REGISTER
If you really want to use MS-DEBUG (or any other debugger!) to examine the operation of Assembly programs, then I advise you to copy these abbreviations onto notecards and try to understand why certain bits (flags) do/don't change in the register for each instruction in the program you're examining. ( Make sure you study the final table below if you'll be reading textbooks which discuss the newer 16-bit Flags Register. Newer 32-bit debuggers, such as Borland's Turbo Debugger, display the same eight Flags as DEBUG, but use an abbreviation for the Name of the Flag and simply show whether it's a 0 or 1 bit.)
This is an 8-bit register that holds 1-bit of data for each of the eight "Flags" which are to be interpreted as follows: Textbook abbrev. for Flag Name => of df if sf zf af pf cf If the FLAGS were all SET (1), -- -- -- -- -- -- -- -- they would look like this... => OV DN EI NG ZR AC PE CY If the FLAGS were all CLEARed (0), they would look like this... => NV UP DI PL NZ NA PO NC FLAGS SET (a 1-bit) CLEARed (a 0-bit) --------------- --------------- ------------------- Overflow of = OV (OVerflow) NV [No oVerflow] Direction df = DN (decrement) UP (increment) Interrupt if = EI (enabled) DI (disabled) Sign sf = NG (negative) PL (positive) Zero zf = ZR [zero] NZ [ Not zero] Auxiliary Carry af = AC NA [ No AC ] Parity pf = PE (even) PO (odd) Carry cf = CY [Carry] NC [ No Carry] ============== The individual abbreviations appear to have these meanings: OV = OVerflow, NV = No oVerflow. DN = DowN, UP (up). EI = Enable Interupt, DI = Disable Interupt. NG = NeGative, PL = PLus; a strange mixing of terms due to the fact that 'Odd Parity' is represented by PO (so it can't be as POsitive here), but they still could have used 'MI' and for the word, MInus; instead of 'NeGative'. ZR = ZeRo, NZ = Not Zero. AC = Auxiliary Carry, NA = Not Auxiliary carry. PE = Parity Even, PO = Parity Odd. CY = CarrY, NC = No Carry.
How Flags are Set in the Registers
The New "FLAGS" Registers
To help you understand the display in MS-DEBUG compared to any Assembly texts which make reference to a 16- or 32-bit FLAGS register, here's the layout of the first 12 bits (11 - 0) for the newer 16- or 32-bit FLAGS Registers:
of df if tf sf zf af pf cf ----------------------------------- Symbols used by MS-DEBUG ----------------------------------- OV DN EI NG ZR AC PE CY ---> When bit = 1 NV UP DI PL NZ NA PO NC ---> When bit = 0 |xx|xx|xx|--|xx|xx| 0|xx| 0|xx| 1|xx| Newer Designations: Bits: 11 10 9 8 7 6 5 4 3 2 1 0 | | | | | | | | | | | '--- CF - Carry Flag | | | | | | | | | | '--- is always a 1 | | | | | | | | | '--- PF - Parity Flag | | | | | | | | '--- is always a 0 | | | | | | | '--- AF - Auxiliary (Carry) Flag | | | | | | '--- is always a 0 | | | | | '--- ZF - Zero Flag | | | | '--- SF - Sign Flag | | | '--- (TF Trap Flag - not shown in MS-DEBUG) | | '--- IF - Interrupt Flag | '--- DF - Direction Flag '--- OF - Overflow Flag
Numeric Examples
If an instruction sets only the Zero (bit 6; zf=1; ZR) and Parity (bit 2; pf=1; PE;
Parity Even) flags, that would result in the following binary number:
0100 0110 (Remember, bit 1 is always set!), so this would result
in a hexadecimal 46 in the 'Flags Register'. If each of these bits were set, one at a time,
the hexadecimal representation of the Flags Register would be as follows:
Bit 11 (of): 1000 0000 0010 = 802 - Overflow (OV)
Bit 10 (df): 0100 0000 0010 = 402 - Direction Down (DN)
Bit 9 (if): 0010 0000 0010 = 202 - Interrupt Enabled (EI)
Bit 7 (sf): 0000 1000 0010 = 82 - Sign Negative (NG)
Bit 6 (zf): 0000 0100 0010 = 42 - Zero (ZR)
Bit 4 (af): 0000 0001 0010 = 12 - Auxiliary Carry (AC)
Bit 2 (pf): 0000 0000 0110 = 06 - Parity Even (PE)
Bit 0 (cf): 0000 0000 0011 = 03 - Carry (CY)
of df if tf sf zf (0) af (0) PF (1) CF = 07
of df if tf sf zf (0) AF (0) pf (1) CF = 13
of df if tf sf ZF (0) af (0) PF (1) cf = 46
of df IF tf sf zf (0) af (0) PF (1) CF = 207
of df IF tf sf ZF (0) af (0) PF (1) cf = 246
of df IF tf sf ZF (0) af (0) PF (1) CF = 247
of df IF tf SF zf (0) af (0) pf (1) cf = 282
of DF IF tf SF zf (0) af (0) pf (1) cf = 682