T-76.4115 Iteration demo T-76.4115 Iteration Demo Team Balboa I1 - Iteration 9.12.2009.
Chapter 6 Integer Manipulation and Iteration...
-
Upload
nguyenphuc -
Category
Documents
-
view
238 -
download
5
Transcript of Chapter 6 Integer Manipulation and Iteration...
135© 2015 Gilbert Ndjatou
Chapter 6
Integer Manipulation
and Iteration Instructions
This chapter discusses some integer manipulation and iteration instructions
available on the Intel 8086 processor.
Integer manipulation instructions are provided to perform the transfer
of signed and unsigned integers from one location inside the computer to
another, to perform the conversion of signed integers between 8 and 16-bit
representations, and to perform arithmetic operations on signed and unsigned
integers.
Iteration instructions are used to repeat the execution of one or more
instructions a certain number of times.
These instructions are discussed by first providing their general syntax in
which an operand is labeled source, destination, or ShortOffset.
A source operand is an immediate data, a register, or a memory location
whose contents are not affected by the execution of the instruction.
A destination operand is a register or a memory location whose contents
are affected by the execution of the instruction.
136
© 2015 Gilbert Ndjatou
A ShortOffset operand is the offset of an instruction such that the
corresponding relative address can be specified as a byte.
When both operands of an instruction are affected by its execution, they
are labeled destination1 for the first and destination2 for the second.
It is important to note that the previous contents of a destination operand
are lost after the execution of an instruction. Information about the settings
of the flags register by each of these instruction is also provided. Additional
information about an instruction such as the format of its operands, its
opcode, and if a ‘mod r/m byte’ is used in its machine language translation
are provided in Appendix 2. As new instructions are presented, we use C
language like assignment statement and arithmetic operators to describe the
operation(s) that they perform on operand(s).
6.1 Data-Transfer Instructions
Data-transfer instructions are instructions that copy a signed or an unsigned
integer into a register or a memory location. In this chapter, we discuss the
MOV (move) and the XCHG (exchange) instructions.
MOV Instructions
The MOV (move) instructions copy an immediate data into a memory
location or a register. They also copy the contents of a register or a memory
location into another register, or the contents of a register into a memory
location. They are defined as follows:
syntax: MOV destination , source
Operation: destination = source
Flags status: unchanged
Both operands of MOV instructions can either be a byte or a word. However,
they must have the same size. Furthermore, the destination operand can only
be a register or a memory location. Example 6.1 illustrates the execution of
these instructions.
137
© 2015 Gilbert Ndjatou
There is no MOV instructions to perform each of the following
operations:
C copy data into the code segment register CS
C copy data into the instruction pointer register IP
C copy a segment register into another segment register
C copy an immediate data into a segment register
C copy a memory location into another memory location.
Example 6.1 Execution of the MOV instructions
In these examples, it is assumed that the initial data are moved into the registers or the memory
locations before the execution of the instructions.
a) MOV BX , 5
Register
BX
Before execution: F1F2
After execution: 0005
b) MOV WORD PTR [DS:200h] , 5
Memory locations
Offset: 0200 0201
Before execution: F1 F2
After execution: 05 00
c) MOV BYTE PTR [DS:200h] , 5
Memory locations
Offset: 0200
Before execution: F1
After execution: 05
d) MOV CX , AX
Registers
CX AX
Before execution: F1F2 000A
After execution: 000A 000A
138
© 2015 Gilbert Ndjatou
e) MOV [DS:200h] , BX
Memory locations Register
Offset: 0200 0201 BX
Before execution: F1 F2 000A
After execution: 0A 00 000A
f) MOV AH , [DS:200h]
Memory locations Register
Offset: 0200 AH
Before execution: 0B F1
After execution: 0B 0B
To copy an immediate data into a segment register (DS, ES, or SS), one
may do the following:
1. first copy the immediate data into a 16-bit register or a word memory
location
2. then copy the contents of that register or memory location to the
segment register.
For example, to copy 2A5Ch into the segment register DS, we may use the
following two instructions:
MOV AX, 2A5Ch
MOV DS, AX
Similarly, you copy the contents of a memory location into another
memory location by first copying it into a register.
XCHG Instructions
The XCHG (exchange) instructions exchange the contents of two registers,
or the contents of a register and a memory location. They are defined as
follows:
139
© 2015 Gilbert Ndjatou
syntax: XCHG destination1, destination2
operation: destination1 = destination2 and
destination2 = destination1
Flags status: unchanged
The operands of the XCHG instructions are either byte or word registers or
memory locations. However, both operands must have the same size and at
least one of the two operands must be a register. Example 6.2 illustrates the
execution of these instructions.
The contents of two memory locations may be interchanged by using a
register and three XCHG instructions as in the following example in which
the word at offset 0200h is interchanged with the word at offset 0210h.
XCHG AX , [DS:200h]
XCHG AX , [DS:210h]
XCHG AX , [DS:200h]
Example 6.2 Execution of the XCHG Instructions
In these examples, it is assumed that the initial data are moved into the registers or the memory
locations before the execution of the instructions.
a) XCHG BX , CX
Registers
BX CX
Before execution: F1F2 A0B0
After execution: A0B0 F1F2
b) XCHG [DS:200h] , BX
Memory locations Register
Offset: 0200 0201 BX
Before execution: F1 F2 000A
After execution: 0A 00 F2F1
140
© 2015 Gilbert Ndjatou
c) XCHG BL , AL
Registers
BL AL
Before execution: F1 A0
After execution: A0 F1
d) XCHG AH , [DS:200h]
Memory locations Register
Offset: 0200 AH
Before execution: 0B F1
After execution: F1 0B
Exercise 6.1
1. Assume that before the execution of each of the following instructions, the contents of the
registers AX, BX, and CX, and the memory locations at offsets 0120 and 0121 in the data
segmentare given as follows:
AX: 0001 Offset: 0120 0121
BX: 0002 Contents: 0A 0B
CX: 0003
Show the contents of the register or memory location operands of each of the following
instructions after its execution:
a. MOV AX, -2 d. MOV CX, BX g. MOV AX, [DS:120]
b. MOV AL, -3 e. MOV AH, CL h. MOV WORD PTR [DS:120], 13
c. MOV [DS:120], BX f. MOV [DS:120], BL i. MOV BYTE PTR [DS:120], -4
2. Write one or more MOV instructions to accomplish each of the following operations:
a. Copy 10 into register BX.
b. Copy 7 into the word in the data segment starting at offset 015Ah.
c. Copy 15A3h into register DS.
d. Copy 9 into the byte in memory at offset 015Ah.
e. Copy the contents of register CX into the word in memory starting at offset 014Bh.
f. Copy the byte in memory at offset 014Ch to the memory at offset 013Eh.
141
© 2015 Gilbert Ndjatou
3. Write one or more XCHG instructions to exchange the contents of the word memory location
at offset 013Ah and the word memory location at offset 012Bh.
6.2 Conversion Instructions
The Intel 8086 processor has an instruction, the CBW (convert byte to word)
instruction, to convert an 8-bit signed integer to 16 bits and another one, the
CWD (convert word to double word) instruction to convert a 16-bit signed
integer to 32 bits.
The CBW instruction converts the 8-bit signed integer in register AL to
16 bits by extending its sign bit to register AH; and the CWD instruction
converts the 16-bit signed integer in register AX to 32 bit by extending its
sign bit to register DX.
CBW Instruction
The CBW instruction extends the sign bit of the 8-bit signed integer in
register AL into register AH. It is defined as follows:
Syntax: CBW
Operation: AH = FFh (if contents of AL is negative); 00h (otherwise).
Flag status: unchanged
CWD Instruction
The CWD instruction extends the sign bit of the 16-bit signed integer in
register AX into register DX. It is defined as follows:
Syntax: CWD
Operation: DX = FFFFh (if contents of AX is negative);
0000h (otherwise).
Flag status: unchanged
142
© 2015 Gilbert Ndjatou
There are no instructions to convert a 32-bit signd integer to 16 bits or a
16-bit signed integers to 8 bits. However, this could be done by just dropping
the high order bits of the integer. To verify that the conversion is correct, one
can verify that the bits dropped are the sign bit of the result of the conversion.
Example 6.3 illustrates the execution of these instructions.
Example 6.3 Execution of the CBW and CWD instructions
In these examples, it is assumed that the initial data are moved into the registers or the memory
locations before the execution of each instruction.
a) CBW
Registers
AX
Before execution: 1A5F
After execution: 005F
b) CBW
Registers
AX
Before execution: 1A9A
After execution: FF9A
c) CWD
Registers
DX AX
Before execution: A0B0 5A2F
After execution: 0000 5A2F
d) CWD
Registers
DX AX
Before execution: A0B0 A123
After execution: FFFF A123
143
© 2015 Gilbert Ndjatou
6.3 Arithmetic Instructions
The Intel 8086 processor has instructions to add, subtract, multiply, and
divide signed and unsigned integers. The instructions discussed in this
chapter are the ADD (addition of sign and unsigned integers) instructions,
the SUB (subtraction of signed and unsigned integers) instructions, the
IMUL (multiplication of signed integers) instructions, the MUL
(multiplication of unsigned integers) instructions, the IDIV (division of
signed integers) instructions, and the DIV (division of unsigned integers)
instructions. We also discuss the INC (increment a signed or unsigned
integer) instructions, the DEC (decrement a signed or unsigned integer)
instructions, and the NEG (negation: take the two’s complement of a signed
integer) instructions.
ADD Instructions
The ADD instructions add the second (source) operand to the first
(destination) operand and the result is assigned to the destination operand.
Both operands are either signed or unsigned integers. The instructions are
defined as follows:
Syntax: ADD destination , source
Operation: destination = destination + source
Flags status: ZF, SF, OF, CF, AF, and PF may be modified.
The operands are either 8-bit or 16-bit integers. However, register and
memory operands must have the same size. When the source operand is an
immediate data, it is represented as a byte if it is in the range, - 128 to 127;
otherwise, it is represented as a 16-bit integer value. Example 6.4 illustrates
the execution of these instructions.
144
© 2015 Gilbert Ndjatou
Example 6.4 Execution of the ADD Instructions
In these examples, it is assumed that the initial data are moved into the registers or the memory
locations before the execution of the instructions.
a) ADD BX , 5
Register
BX
Before execution: 0004
After execution: 0009
b) ADD WORD PTR [DS:200h] , 5
Memory locations
Offset: 0200 0201
Before execution: 04 00
After execution: 09 00
c) ADD BYTE PTR [DS:200h] , 5
Memory locations
Offset: 0200
Before execution: 04
After execution: 09
d) ADD CX , AX
Registers
CX AX
Before execution: 0004 000B
After execution: 000F 000B
e) ADD [DS:200h] , BX
Memory locations Register
Offset: 0200 0201 BX
Before execution: 04 00 000B
After execution: 0F 00 000B
f) ADD AH , [DS:200h]
Memory locations Register
Offset: 0200 AH
Before execution: 0B 04
After execution: 0B 0F
145
© 2015 Gilbert Ndjatou
SUB Instructions
The SUB instructions subtract the second (source) operand from the first
(destination) operand and the difference is assigned to the destination
operand. Both operands are either signed or unsigned integers. The
instructions are defined as follows:
Syntax: SUB destination , source
Operation: destination = destination - source
Flags status: ZF, SF, OF, CF, AF, and PF may be modified.
As with the ADD instructions, the operands are either 8-bit or 16-bit integers.
However, register and memory operands must have the same size. When the
source operand is an immediate data, it is represented as a byte if it is in the
range - 128 to 127); otherwise, it is represented as a 16-bit integer. Example
6.5 illustrates the execution of these instructions.
Example 6.5 Execution of SUB Instructions
In these examples, it is assumed that the initial data are moved into the registers or the memory
locations before the execution of each instruction.
a) SUB BX , 5
Register
BX
Before execution: 0009
After execution: 0004
b) SUB WORD PTR [DS:200h] , 5
Memory locations
Offset: 0200 0201
Before execution: 09 00
After execution: 04 00
146
© 2015 Gilbert Ndjatou
c) SUB BYTE PTR [DS:200h] , 5
Memory locations
Offset: 0200
Before execution: 09
After execution: 04
d) SUB CX , AX
Registers
CX AX
Before execution: 000B 0004
After execution: 0007 0004
e) SUB [DS:200h] , BX
Memory locations Register
Offset: 0200 0201 BX
Before execution: 0B 00 0004
After execution: 07 00 0004
f) SUB AH , [DS:200h]
Memory locations Register
Offset: 0200 AH
Before execution: 04 0B
After execution: 04 07
Figure 6.1 illustrates a Debug program that uses MOV, ADD and SUB
instructions.
Figure 6.1 A Sample Debug Program (using MOV, ADD and SUB instructions)
The following sequence of assembly language instructions computes the arithmetic expression:
6 - 10 + (-15) + 20 - (-7), and stores the result in register DX.
147
© 2015 Gilbert Ndjatou
Instructions Remarks
MOV AX, 6 ; AX = 6
SUB AX, 0A ; AX = 6 - 10
ADD AX, -0F ; AX = 6 - 10 + (-15)
ADD AX, 14 ; AX = 6 - 10 + (-15) + 20
SUB AX, -7 ; AX = 6 - 10 + (-15) + 20 - (-7)
MOV DX, AX ; DX = AX
INT 20
Exercise 6.2
1. Write the arithmetic expression to be evaluated by the execution of the following sequence of
instructions:
MOV AX, 9
MOV BX, 6
ADD AX, 3
SUB BX, 4
SUB AX, BX
2. Trace the execution of the above sequence of statements and show the contents of the registers
AX and BX.
3. Write a sequence of assembly language instructions to evaluate each of the following arithmetic
expressions:
a. 8 + 25 - 11 + (-5) - 7 + 2 b. 12 - 5 + 9 - ( 4 + 11 - 9) + 2
Signed and Unsigned Multiplications
The Intel 8086 processor has signed and unsigned multiplication instructions
for the multiplication of 8-bit values or 16-bit values.
8-bit multiplication instructions expect the first operand to be in register
AL and the second to be in an 8-bit register or a memory location. 16-bit
multiplication instructions expect the first operand to be in register AX, and
the second operand to be in a 16-bit register or a memory location.
148
© 2015 Gilbert Ndjatou
The result of an 8-bit multiplication instruction is a 16-bit value that is
stored in register AX. The overflow and the carry flags are set if the product
is larger than a byte.
The result of a 16-bit multiplication instruction is a 32-bit value that is
stored in the register pair (DX, AX): The high order bytes are stored in
register DX, and the low order bytes in register AX. The overflow and the
carry flags are set if the result is larger than a word.
The difference between signed and unsigned multiplications is that signed
multiplication instructions extend the sign bit of the result through the leading
bits, while the unsigned instructions set the leading bits to 0.
The first operand of a multiplication instruction (register AL for 8-bit
multiplications and register AX for 16-bit multiplications) is implicit: only
the second operand is specified in the instruction. These instructions are
specified as follows:
IMUL (signed multiplication) Instructions
Syntax: IMUL source-16 or IMUL source-8
Operation: (DX, AX) = AX * source-16 | AX = AL * source-8
Flags status: OF and CF may be modified.
source-16 is a 16-bit register or memory location and source-8 is an 8-bit
register or memory location.
MUL (unsigned multiplication) Instructions
Syntax: MUL source-16 or MUL source-8
Operation: same as for IMUL instructions
Flags status: OF and CF may be modified.
Example 6.6 illustrates the execution of IMUL (signed multiplication)
instructions and Example 6.7 illustrates the execution of MUL (unsigned
multiplication) instructions.
149
© 2015 Gilbert Ndjatou
Example 6.6 Execution of IMUL (signed multiplication) Instructions
In these examples, it is assumed that the initial data are moved into the registers or the memory
locations before the execution of each instruction.
a) IMUL BX ; 0005 * 0002 (decimal 5 * 2)
Registers
DX AX BX
Before execution: A1B2 0005 0002
After execution: 0000 000A 0002 Result = 0000 000A
b) IMUL CX ; 0005 * FFFE (decimal 5 * -2)
Registers
DX AX CX
Before execution: A1B2 0005 FFFE
After execution: FFFF FFF6 FFFE Result = FFFF FFF6
c) IMUL BL ; 05 * 02 (decimal 5 * 2)
Registers
AX BX
Before execution: 1B05 2C02
After execution: 000A 2C02 Result = 000A
d) IMUL CL ; 05 * FE (decimal 5 * -2)
Registers
AX CX
Before execution: 1B05 2CFE
After execution: FFF6 2CFE Result: FFF6
150
© 2015 Gilbert Ndjatou
e) IMUL WORD PTR [DS:200h] ; 0005 * 0002
Memory locations Registers
Offset: 0200 0201 DX AX
Before execution: 02 00 A1B2 0005
After execution: 02 00 0000 000A Result: 0000 000A
f) IMUL BYTE PTR [DS:200h] ; 05 * FE
Memory locations Registers
Offset: 0200 AX
Before execution: FE 1B05
After execution: FE FFF6 Result: FFF6
Example 6.7 Execution of MUL (unsigned multiplication) Instructions
In these examples, it is assumed that the initial data are moved into the registers or the memory
locations before the execution of each instruction.
a) MUL BX ; 0005 * 0002 (decimal 5 * 2)
Registers
DX AX BX
Before execution: A1B2 0005 0002
After execution: 0000 000A 0002 Result = 0000 000A
b) MUL CX ; 0005 * FFFE (decimal 5 * 65534)
Registers
DX AX CX
Before execution: A1B2 0005 FFFE
After execution: 0004 FFF6 FFFE Result = 0004 FFF6
151
© 2015 Gilbert Ndjatou
c) MUL BL ; 05 * 02 (decimal 5 * 2)
Registers
AX BX
Before execution: 1B05 2C02
After execution: 000A 2C02 Result = 000A
d) MUL CL ; 05 * FE (decimal 5 * 254)
Registers
AX CX
Before execution: 1B05 2CFE
After execution: 04F6 2CFE Result = 04F6
Figure 6.2 illustrates a Debug program that uses IMUL (signed
multiplication), MOV, ADD and SUB instructions.
Figure 6.2 A sample Debug program that uses MOV, ADD, SUB, and IMUL
instructions
The following sequence of assembly language instructions computes the arithmetic expression:
6 - 10 * (-15) + 20, and stores the result in register CX.
Instructions Remarks
MOV CX, 6 ; CX = 6
MOV AX, 0A ; AX = 10
MOV BX, -0F
IMUL BX ; (DX, AX) = 10 * (-15)
SUB CX, AX ; CX = 6 - 10 * (-15)
ADD CX, 14 ; CX = 6 - 10 * (-15) + 20
INT 20
152
© 2015 Gilbert Ndjatou
Exercise 6.3
1. Write a sequence of assembly language instructions to compute each of the following arithmetic
expressions:
a. 5 + 7 * 9 b. 6 * 7 - 8
2. Write the arithmetic expression to be evaluated by the execution of the following sequence of
instructions:
MOV AX, 9
MOV BX, 6
IMUL BX
ADD BX, 2
SUB AX, BX
3. Trace the execution of the above sequence of instructions and show the contents of the registers
AX and BX.
4. Write a sequence of assembly language instructions to evaluate each of the following arithmetic
expressions:
a. 8 + 11 * (-5) + 25 - 7 * 2 b. 12 * 5 + 9 * ( 4 + 11 - 9) + 2
Signed and Unsigned Divisions
The Intel 8086 processor has signed and unsigned division instructions to
divide 32-bit values by 16-bit values, and 16-bit values by 8-bit values.
Instructions to divide16-bit values by 8-bit values expect the dividend to
be in register AX and the divisor to be in an 8-bit register or memory
location; and instructions to divide 32-bit values by 16-bit values expect the
dividend to be in the register pair (DX, AX), and the divisor to be in a 16-bit
register or memory location.
Division instructions produce a quotient and a remainder: the quotient of
a 16-bit by 8-bit division instructions is stored in register AL, and the
remainder in register AH; for 32-bit by 16-bit division instructions, the
quotient is stored in register AX, and the remainder in register DX.
153
© 2015 Gilbert Ndjatou
As with multiplication instructions, the first operand, (register AX for the
16-bit by 8-bit division, and the register pair (DX, AX) for the 32-bit by 16-
bit division) is implicit: only the second operand is specified in the
instruction. These instructions are specified as follows:
IDIV (signed division) Instructions
Syntax: IDIV source-16 or
IDIV source-8
Operation:
AX = quotient, DX = remainder of (DX, AX) ÷ source-16
AL = quotient, AH = remainder of AX ÷ source-8
Flags status: OF, SF, ZF, AF, PF and CF are undefined.
DF, IF, and TF are unchanged
source-16 is a 16-bit register or memory location, and source-8 is an 8-bit
register or memory location.
DIV (unsigned division) Instructions
Syntax: IDIV source-16 or
IDIV source-8
Operation: same as for IDIV instructions
Flags status: same as for IDIV instructions.
Example 6.8 illustrates the execution of IDIV (signed division) instructions
and Example 6.9 illustrates the executions of DIV (unsigned division)
instructions.
154
© 2015 Gilbert Ndjatou
Example 6.8 Execution of IDIV (signed division) instructions
In these examples, it is assumed that the initial data are moved into the registers or the memory
locations before the execution of the instructions.
a) IDIV BX ; 0000 000B ÷ 0004 (decimal 11 ÷ 4)
Registers
DX AX BX
Before execution: 0000 000B 0004
After execution: 0003 0002 0004
Remainder: 0003 (decimal 3) Quotient: 0002 (Decimal 2)
b) IDIV CX ; FFFF FFF5 ÷ 0004 (decimal -11 ÷ 4)
Registers
DX AX CX
Before execution: FFFF FFF5 0004
After execution: FFFD FFFE 0004
Remainder: FFFD (decimal -3) Quotient: FFFE (Decimal - 2)
c) IDIV BX ; 0000 000B ÷ FFFC (decimal 11 ÷ -4)
Registers
DX AX BX
Before execution: 0000 000B FFFC
After execution: 0003 FFFE FFFC
Remainder: 0003 (decimal 3) Quotient: FFFE (Decimal - 2)
d) IDIV BL ; 000B ÷ 04 (decimal 11 ÷ 4)
Registers
AX BX
Before execution: 000B 2C04
After execution: 0302 2C04
Remainder: 03 (decimal 3) Quotient: 02 (Decimal 2)
155
© 2015 Gilbert Ndjatou
e) IDIV WORD PTR [DS:200h] ; 0000 000B ÷ 0004 (decimal 11 ÷ 4)
Memory locations Registers
Offset: 0200 0201 DX AX
Before execution: 04 00 0000 000B
After execution: 04 00 0003 0002
Remainder: 0003 (decimal 3) Quotient: 0002 (Decimal 2)
f) IDIV BYTE PTR [DS:200h] ; 000B ÷ 04 (decimal 11 ÷ 4)
Memory locations Registers
Offset: 0200 AX
Before execution: 04 000B
After execution: 04 0302
Remainder: 03 (decimal 3) Quotient: 02 (Decimal 2)
Example 6.9 Executions of DIV (unsigned division) instructions
In these examples, it is assumed that the initial data are moved into the registers or the memory
locations before the execution of the instructions.
a) DIV BX ; 0000 000B ÷ 0004 (decimal 11 ÷ 4)
Registers
DX AX BX
Before execution: 0000 000B 0004
After execution: 0003 0002 0004
Remainder: 0003 (decimal 3) Quotient: 0002 (Decimal 2)
156
© 2015 Gilbert Ndjatou
b) DIV CX ; 0000 FFF5 ÷ 0004 (decimal 65525 ÷ 4)
Registers
DX AX CX
Before execution: 0000 FFF5 0004
After execution: 0001 3FFD 0004
Remainder: 0001 (decimal 1) Quotient: 3FFD (Decimal 16381)
Note that when both the dividend and the divisor are positive, the IDIV
(signed division) and DIV (unsigned division) instructions produce the same
results.
When the quotient is outside of the range of values that can be
represented by the destination operand, an interrupt is generated. The handler
for this interrupt usually terminates the program with an error message. An
attempt to divide by 0 also generates this interrupt.
Signs of the Quotient and the Remainder
In Arithmetic, the remainder of a division is always positive or zero, and is
less than the divisor. However, as you may have noticed in Example 6.8 a)
and b), the remainder of a signed division instruction may be a negative
integer. In general, non-zero remainders have the same sign as the dividend.
That means, a non-zero remainder is positive if the dividend is positive, and
negative otherwise.
You may also observe in Example 6.8 that the quotient is negative if the
dividend and the divisor have opposite signs and positive if both the dividend
and the divisor have the same sign. It is zero if the dividend is zero.
Preparing the Dividend of a 32-bit Division
In order to specify a 32-bit by 16-bit division, an extra step must be taken to
prepare the dividend because it extends over two registers.
157
© 2015 Gilbert Ndjatou
For an unsigned division, if the dividend is a 16-bit value, zero must be
moved into register DX. The dividend may then be prepared as follows:
C move the dividend into register AX
C Move zero into register DX
For a signed division, if the dividend is a 16-bit value, its sign must be
extended into register DX. This may be accomplished as follows:
C move the dividend into register AX
C use the CWD instruction to extend its sign bit to register DX.
Example 6.10 provides the sequence of instructions to perform a 32-bit
unsigned division and Example 6.11 provides the sequence of instructions to
perform a 32-bit signed division.
Example 6.10 Instructions to perform unsigned divisions.
Write a Debug program to compute 35/ 4 using an unsigned division instruction.
Program using 32-bit division
MOV BX , 4 ; BX = 4
MOV AX , 23 ; AX = 35
MOV DX, 0 ; (DX - AX) = 35
DIV BX ; DX = remain., AX = quot.
INT 20
Program using 16-bit division
MOV BL , 4 ; BL = 4
MOV AX , 23 ; AX = 35
DIV BL ; AH = remain., AL = quot.
INT 20
158
© 2015 Gilbert Ndjatou
Example 6.11 Instructions to perform signed divisions.
Write a Debug program to compute -35/ 4 using a signed division instruction.
Program using 32-bit division
MOV BX , 4 ; BX = 4
MOV AX , -23 ; AX = -35
CWD ; (DX - AX) = -35
IDIV BX ; DX = remain., AX = quot.
INT 20
Program using 16-bit division
MOV BL , 4 ; BL = 4
MOV AX , -23 ; AX = -35
IDIV BL ; AH = remain., AL = quot.
INT 20
Sample Computations
The following programs illustrate the concepts introduced so far in this
chapter. They combine data transfer instructions, conversion instructions,
and integer arithmetic instruction to perform computations. Both programs
compute arithmetic expressions.
Figure 6.3
Debug program to compute the arithmetic expression:
2 - 5 * 12 + 10 - (-30)/6 + 50 and load the result in register DX.
The remainder of the division is ignored.
Instructions Remarks
MOV CX, 2 ; CX = 2
MOV AX, 5 ; multiplication must be performed first
MOV BX, 0C
IMUL BX ; (DX AX) = 5 * 12
SUB CX, AX ; CX = 2 - 5 * 12
159
© 2015 Gilbert Ndjatou
ADD CX, 0A ; CX = 2 - 5 * 12 + 10
MOV AX, -1E ; perform division first
CWD ; (DX AX) = -30
MOV BX, 6
IDIV BX ; AX = quotient of -30 / 6
SUB CX, AX ; CX = 2 - 5 * 12 + 10 - (-30)/6
ADD CX, 32 ; CX = 2 - 5 * 12 + 10 - (-30)/6 + 50
MOV DX, CX ; copy the result to DX
INT 20
Figure 6.4
Suppose that there are signed integers n and m in the main memory at offsets 0120 and
0130 respectively. The following Debug program computes the arithmetic expression:
n + m * n - (n + m) / m and load the result in register DX.
The remainder of the division is ignored. It is also assumed that the product can be
represented as a word (in register AX).
Instructions Remarks
MOV CX, [DS:120] ; CX = n
MOV AX, [DS:120] ; perform multiplication first
IMUL WORD PTR [DS:130] ; (DX, AX) = m * n
ADD CX, AX ; CX = n + m * n
MOV AX, [DS:120] ; perform the expression in parentheses first
ADD AX, [DS:130] ; AX = n + m
; then perform the division
CWD ; (DX, AX) = n + m
IDIV WORD PTR [DS:130] ; AX = quotient of (n + m) / m
SUB CX, AX ; CX = n + m * n - (n + m) / m
MOV DX, CX ; copy the result to DX
INT 20
160
© 2015 Gilbert Ndjatou
Exercise 6.4
1. For each of the following contents of registers AX, BX, and DX, execute the instruction
IDIV BX
and show the contents of these registers after the execution:
a. AX: 0007 BX: 0002 DX: 0000
b. AX: FFF9 BX: 0002 DX: FFFF
c. AX: 0007 BX: FFFE DX: 0000
d. AX: FFF9 BX: FFFE DX: FFFF
2. Write a sequence of assembly language instructions to execute each of the following operations
in the Debug environment:
a. 25 / 7 b. -38 / 11
3. Write a sequence of assembly language instructions to execute each of the following arithmetic
expressions in the Debug environment and load the result in register CX:
a. 15 + 19 / 6 - 4 * 7 - 13 b. 12 + 5 * 4 - (-38) /(11 + 6 - 3) + 5
4. Write a sequence of assembly language instructions (to be executed in the Debug environment)
to convert the Fahrenheit temperature 89 to Celsius and load the result in register CX. The
formula for this conversion is
C = 5 / 9 x (F - 32)
5. Write a sequence of assembly language instructions (to be executed in the Debug environment)
to load a three-digit positive integer value in register AX, and to add all its digits and load the
result in register CX.
Increment, Decrement, and Negation Instructions
The Intel 8086 processor also has instructions to add 1 to the contents of a
register or memory location, to subtract 1 from the contents of a register or
memory location, and to take the two’s complement of a signed integer.
These instructions are named respectively, INC (increment instructions),
DEC (decrement instructions), and NEG (negation instructions).
161
© 2015 Gilbert Ndjatou
INC instructions
The INC (increment) instructions add one to their operand. The operand is
either a signed or unsigned integer in a register or a memory location. They
are defined as follows:
Syntax: INC destination
Operation: destination = destination + 1
Flags status: ZF, SF, OF, AF, and PF may be modified.
The destination operand is an 8-bit register or memory location, or a 16-bit
register (that is not a segment register) or memory location. Example 6.12
illustrates the execution of these instructions.
DEC instructions
The DEC (decrement) instructions subtract one from their operand. The
operand is a signed or an unsigned integer in a register or a memory location.
They are defined as follows:
Syntax: DEC destination
Operation: destination = destination - 1
Flags status: ZF, SF, OF, AF, and PF may be modified.
The destination operand is an 8-bit register or memory location, or a 16-bit
register (that is not a segment register) or memory location. Example 6.12
illustrates the execution of these instructions.
NEG instructions
The NEG (negation) instructions subtract the contents of a register or a
memory location operand from zero and then replaces the original contents
with the result. These instructions are defined as follows:
162
© 2015 Gilbert Ndjatou
Syntax: NEG destination
Operation: destination = 0 - destination
Flags status: ZF, SF, OF, AF, and PF may be modified.
CF is set if destination is not 0.
The destination operand is either an 8-bit register or memory location, or a
16-bit register (that is not a segment register) or memory location. An
attempt to negate the smallest 8-bit or 16-bit signed integer will produce an
overflow condition. Example 6.12 illustrates the execution of these
instructions in the Debug environment.
Example 6.12 Executions of INC, DEC, and NEG instructions in the Debug
environment
It is assumed that the initial data is moved into the registers or the memory locations before the
execution of each instruction.
a) INC BX
Registers
BX
Before execution: 0009
After execution: 000A
b) INC BYTE PTR [200h]
Memory locations
Offset: 0200
Before execution: 05
After execution: 06
c) DEC BL
Registers
BL
Before execution: 0A
After execution: 09
163
© 2015 Gilbert Ndjatou
d) DEC WORD PTR [200h]
Memory locations
Offset: 0200 0201
Before execution: 0B 00
After execution: 0A 00
e) NEG AX
Registers
AX
Before execution: 0001
After execution: FFFF
f) NEG BYTE PTR [200h]
Memory locations
Offset: 0200
Before execution: FE
After execution: 02
6.4 Iteration Instruction
An iteration instruction is an instruction that specifies that the execution of
one or more instructions be repeated a certain number of times. The iteration
instruction provided by the Intel 8086 processor is the Loop instruction with
mnemonic opcode LOOP. For this instruction, the count register CX must
contain the number of times the execution must be repeated. It is defined as
follows:
Loop Instruction
Syntax: LOOP ShortOffset
Operation:
1. CX := CX - 1
2. If CX <> 0 then IP = ShortOffset
Otherwise, continue with the next instruction.
Flags: none of the flags is affected.
164
© 2015 Gilbert Ndjatou
In the above definition, ShortOffset is the offset of the first instruction in
the sequence of instructions (or body of the loop) whose execution must be
repeated. The size of the body of the loop must be less than or equal to 126
bytes. This implies that the relative address of the first instruction in the body
of the loop (with respect to the Loop instruction) must be specified as a byte.
Note that if count is the initial value in register CX, then the Loop
instruction will repeat the execution of each instruction in the body of the
loop count times. Example 6.13 illustrates the execution of Loop instructions
that are used to change the contents of consecutive memory locations.
Example 6.13 Tracing Programs that use the Loop Instruction to affect the
Contents of Consecutive Memory Locations.
Memory Locations at Offset:
Inst. # AL BX CX 0200 0201 0202
Offset Instructions ? ? ? ? ? ?
0100 MOV CX, 3 1 ? ? 00 03 ? ? ?
103 MOV BX, 200 2 ? 02 00 00 03 ? ? ?
106 MOV AL, 4E 3 4E 02 00 00 03 ? ? ?
108 MOV [BX], AL 4 4E 02 00 00 03 4E ? ?
10A SUB AL, 4 5 4A 02 00 00 03 4E ? ?
10C INC BX 6 4A 02 01 00 03 4E ? ?
10D LOOP 108 7 4A 02 01 00 02 4E ? ?
10F INT 20 4 4A 02 01 00 02 4E 4A ?
5 46 02 01 00 02 4E 4A ?
6 46 02 02 00 02 4E 4A ?
7 46 02 02 00 01 4E 4A ?
4 46 02 02 00 01 4E 4A 46
5 44 02 02 00 01 4E 4A 46
6 44 02 03 00 01 4E 4A 46
7 44 02 03 00 00 4E 4A 46
165
© 2015 Gilbert Ndjatou
Memory Locations at Offset:
Inst. # BX CX 0200 0201 0202 0204
Offset Instructions ? ? 06 00 0A 00
0100 MOV CX, 2 1 ? 00 02 06 00 0A 00
0103 MOV BX, 200 2 02 00 00 02 06 00 0A 00
0106 ADD WORD PTR [BX], 5 3 02 00 00 02 0B 00 0A 00
0109 ADD BX, 2 4 02 02 00 02 0B 00 0A 00
010C LOOP 106 5 02 02 00 01 0B 00 0A 00
010E INT 20 3 02 02 00 01 0B 00 0F 00
4 02 04 00 01 0B 00 0F 00
5 02 04 00 00 0B 00 0F 00
Sample Program
We discuss here a sample program that uses the Loop instruction.
Problem Statement
Given the fullword binary integers e and n, write a Debug program to
compute the e power of n, n . Assume that e > 0 and that e and n are suchth e
that the result will be a word. e is stored in the data segment at offset 0120
and n is stored at offset 0130. The result will be stored at offset 0140.
Program Logic
This program requires you to copy 1 into register AX, and then multiply the
contents of register AX by n e times. After the first iteration of the loop,
register AX will contain n , and after the second iteration, it will contain n ,1 2
. . . , and after the e iteration, it will contain n . In order to use the LOOPth e
instruction to accomplish this, you must first load e into register CX. The
desired algorithm is described in pseudocode as follows:
166
© 2015 Gilbert Ndjatou
CX ² e
AX ² 1
REPEAT e times
(DX AX) ² AX * n
END REPEAT
save the result: store AX
The instructions of this program are provided in Figure 6.5. Note that every
time the Loop instruction is executed, 1 is subtracted from the value in
register CX and the new value is compared to 0. If it is greater than 0, then
the instruction at offset 0107 is executed again, followed by the other
instructions in the sequence until the Loop instruction; if it is 0, then the
iteration stops and the instruction that follows the Loop instruction at offset
010D is executed.
Figure 6.5
Given the fullword binary integers e stored at offset 0120 and n stored at offset 0130, compute
n and store the result at offset 0140. e > 0 and e and n are such that the result is a word.e
offset Instructions Remarks
0100 MOV CX , [DS:120] ; repeat e times
0104 MOV AX , 1
0107 IMUL WORD PTR [DS:130] ; (DX, AX) = AX * n
010B LOOP 107 ; if CX > 0 jump to 0107; otherwise continue
010D MOV [DS:140] , AX ; store the result
0110 INT 20
;
; data
0120 DW 4 ; exponent
0130 DW 0C ; number
0140 DW 0 ; reserved for the result
167
© 2015 Gilbert Ndjatou
6.5 Processing One-Dimensional Arrays
In High-level languages, a one-dimensional array is a structure that contains
values of the same data type, and is ordered in such a way that individual
values may be accessed either by their relative position in the structure or by
using a pointer variable. In the first case, the relative position is written in
parentheses or in brackets and is called a subscript. In the second case, a
pointer variable is first initialized to the offset of the first element of the
array, and then, is incremented to moved to the next one. For example, in
C/C++ programming language, an array of ten integers called list is defined
by providing the data type, int of its elements, and the number of elements in
the array as follows:
int list[10];
The elements of this array occupy consecutive memory locations and could
be defined in assembly language by using the define directive introduced in
chapter 4 as follows:
DW 10 DUP (?)
This definition includes the size of the elements of the array (which in this
case is two) and the number of elements in the array, ten.
In some high-level languages, it is possible to specify the initial values for
the elements of an array when that array is defined. For example, the
following C/C++ definition creates an array of five signed integers and
initializes its elements with the integer constants provided in braces:
int list[] = {3, -5, 31, 16, -17};
The elements of this array could be defined in assembly language by using
the define directive as follows:
DW 3, -5, 31, 16, -17
The elements of an array of ten bytes could also be defined as follows:
DB 10 DUP (?)
Note that in these definitions we do not specify the data type of the elements
of the array. For example, the elements of an array of five bytes could be
defined and initialized with 8-bit signed integer values as follows:
168
© 2015 Gilbert Ndjatou
DB 12, -5, -21, 10, 23
It could also be initialized with five character values as follows:
DB ‘KABIL’
Using Register Indirect Addressing with Arrays
In some high-level languages, individual elements on an array can be
accessed by using a pointer variable that is incremented to point to the next
element. For example, in the C/C++ programming language, a pointer
variable can be used to access the elements of the above array list in order to
compute their sum as follows:
int sum = 0;
int * pt;
for (pt = list; pt < list + 5; pt ++)
sum = *pt + sum;
This method of accessing the element of an array is implemented in assembly
language by using the register indirect addressing discussed in chapter 4. In
the program in Figure 6.6, we use register BX to hold the offset of the array
elements. Note that register SI or DI could also be used.
Sample Program 1
Problem Statement
An array of five fullword signed integers is stored in memory starting at
offset 0120. Write a Debug program to compute the average of the elements
of this array. The remainder of the division is ignored and the result
(quotient) is stored at offset 0130.
169
© 2015 Gilbert Ndjatou
Program Logic
This problem requires you to copy 0 into a register (register AX), and then
add each of the five elements of the array to register AX: after the first
iteration of the loop, the first element will be in register AX; after the second
iteration, the sum of the first two elements will be in register AX; . . . ; and
after the fifth iteration, the sum of all the five elements will be in register AX.
The sum of the five elements is then divided by five to get the average.
In order to use the LOOP instruction to add all the elements of this array
to register AX, you must first load 5 into register CX. You must also load
into register BX the offset of the first element of the array. Register BX is
then incremented by 2 in the body of the loop in order to point to the next
element of the array. The desired algorithm is described in pseudocode as
follows:
CX ² 5
AX ² 0
BX ² 120
REPEAT 5 times
AX ² AX + (BX ÷element)
BX ² BX + 2
END REPEAT
(DX , AX) = (DX , AX) ÷ 5
save the result: store AX
The instructions of this program are provided in Figure 6.6.
Figure 6.6
Debug program to compute the average of the elements of an array of five fullword signed
integers using register indirect addressing. The elements of the array are stored in
memory starting at offset 0120. The remainder of the division is ignored, and the result
(quotient) is stored in memory at offset 0130.
170
© 2015 Gilbert Ndjatou
offset Instructions Remarks
0100 MOV CX, 5 ; repeat 5 times
0103 MOV AX, 0
0106 MOV BX, 120 ; BX points to the first element
0109 ADD AX, [BX] ; AX ² AX + (BX ÷ element)
010B ADD BX, 2 ; BX points to next element
010E LOOP 109 ; if CX > 0 jump to 0109; otherwise, continue
0110 CWD ; (DX, AX) = sum of the elements
0111 MOV BX, 5 ; reuse BX to hold the number of elements
0114 IDIV BX ; AX = average
0116 MOV [DS:130], AX ; store the result
011A INT 20
;
; data
0120 DW 23, FFF4, 5, FFFD, 16 ; array
0130 DW 0 ; reserved for the average
Using Indexed Addressing or Base Relative
Addressing with Arrays
In High-level languages, individual elements of an array can also be accessed
by using their relative position in the array. The relative position of an
element is written in parentheses or in brackets as in the following C/C++
code segment:
int i, sum = 0;
for ( i = 0; i < 10; i ++)
sum = list[i] + sum;
This method of accessing the elements of an array can be implemented in
assembly language by using the indexed addressing mode or the base relative
addressing mode introduced in chapter 4. In the following sample programs,
we will use the indexed addressing mode. But, it is understood that the base
relative addressing could also be used by replacing register SI or DI with
register BX, or with register BP if the array is in the stack.
171
© 2015 Gilbert Ndjatou
Sample Program 2
Problem Statement
the problem statement is the same as in Sample Program 1.
Program Logic
This problem requires you to copy 0 into a register (register AX), and then
add each of the five elements of the array to register AX: after the first
iteration of the loop, the first element will be in register AX; after the second
iteration, the sum of the first two elements will be in register AX; . . . ; and
after the fifth iteration, the sum of all the five elements will be in register AX.
The sum of the five elements is then divided by five to get the average.
In order to use the LOOP instruction to add all the elements of this array
to register AX, you must first load 5 into register CX. You must also load
into register DI, 0: the relative position of the first element of the array is 0.
Register DI is then incremented by 2 in the body of the loop in order to hold
the relative position of the next element of the array. The desired algorithm
is described in pseudocode as follows:
CX ² 5
AX ² 0
DI ² 0
REPEAT 5 times
AX ² AX + 120[DI]
DI ² DI + 2
END REPEAT
(DX , AX) = (DX , AX) ÷ 5
save the result: store AX
The instructions of this program are provided in Figure 6.7.
172
© 2015 Gilbert Ndjatou
Figure 6.7
Debug program to compute the average of the elements of an array of five fullword signed
integers using the direct indexed addressing. The elements of the array are stored in
memory starting at offset 0120. The remainder of the division is ignored and the result
(quotient) is stored in memory at offset 0130.
offset Instructions Remarks
0100 MOV CX, 5 ; repeat 5 times
0103 MOV AX, 0
0106 MOV DI, 0 ; DI holds the relative position of the first element
0109 ADD AX, [DI + 120] ; AX ² AX + 120[DI]
010C ADD DI, 2 ; DI holds relative position of next element
010F LOOP 109 ; if CX > 0 jump to 0109; otherwise, continue
0111 CWD ; (DX, AX) = sum of the elements
0112 MOV BX, 5 ; BX holds the number of elements
0115 IDIV BX ; AX = average
0117 MOV [DS:130], AX ; store the result
011B INT 20
;
; data
0120 DW 23, FFF4, 5, FFFD, 16 ; array
0130 DW 0 ; reserved for the average
Sample Program 3
Problem Statement
Write a Debug program to add 25 to each element of an array A of 5 word
signed integers, and to construct another array B such that:
B[i] = 25 + A[i].
Assume that the elements of Array A are stored in memory starting at
offset 0120, and that the elements of array B will be stored in memory
starting at offset 0130.
173
© 2015 Gilbert Ndjatou
Program Logic
The elements of array A are accessed by using an operand in direct indexed
addressing mode in which the displacement is the offset of the first element
of the array, 0120. Similarly, the elements of array B are accessed by using
an operand in direct indexed addressing mode in which the displacement is
the offset of the first element of the array, 0130.
Since both arrays are processed in parallel, the index register SI is used
as the index in both arrays. It is first initialized to 0, and then incremented by
2 after the processing of each pair of array elements (one in array A and the
other in array B).
In order to use the LOOP instruction to process all the elements of both
arrays, you must first load 5 into register CX. The desired algorithm is
described in pseudocode as follows:
CX ² 5
SI ² 0
REPEAT 5 times
130[SI] ² 120[SI] + 5
SI ² SI + 2
END REPEAT
The corresponding program is provided in Figure 6.8.
Figure 6.8
Debug Program to compute B[i] = A[i] + 25. The elements of array A and array B are
stored in memory starting at offset 0120, and offset 0130 respectively.
offset Instructions
0100 MOV CX, 5 ; loop 5 times
0103 MOV SI, 0 ; initialize index to 0
174
© 2015 Gilbert Ndjatou
0106 MOV AX, [SI + 120] ; AX := A[SI]
010A ADD AX, 19 ; AX := A[SI] + 25
010D MOV [SI + 130], AX ; B[SI] := A[SI] + 25
0111 ADD SI, 2 ; SI := SI + 2
0113 LOOP 106 ; if CX <> 0 branch back
0115 INT 20
;
0120 DW 4, FFFB, 0A, FFF1, 14
0130 DW 0, 0, 0, 0, 0
Exercise 6.5
Note: In order to write the fallowing programs, assume that the first instruction in the body -of-the-
loop is at offset 0000; then as you assemble the program in the Debug environment, fill in
its offset in the LOOP instruction.
1. Write a Debug program to compute the sum of the first 10 positive integer values and to store
the result in the data segment at offset 0130.
2. Write a Debug program to compute the product of the first 10 positive integer values and to store
the result in the data segment at offset 0130.
3. Write a Debug program to compute the sum of the first 10 positive multiples of 5 and to store
the result in the data segment at offset 0130.
4. An integer value is stored in the data segment at offset 0120. Write a debug program to compute
the 5 power of this integer value and to store the result in the data segment at offset 0130.th
Assume that the result is a word.
5. An array A of ten word two’s complement binary integers is stored in the data segment starting
at offset 0120. Write a Debug program to add 5 to each element of this array. That means A[i]
= A[i] + 5.
6. An array A of ten word two’s complement binary integers is stored in the data segment starting
at offset 0120. Write a Debug program to subtract 15 to each element of this array and to store
the result into the corresponding element of an array B that will be stored into the data segment
starting at offset 0130 . That means B[i] = A[i] - 15.
175
© 2015 Gilbert Ndjatou
7. Two arrays A and B of ten word two’s complement binary integers are stored in the data
segment starting at offset 0120 and 0130 respectively. Write a Debug program to subtract from
each element of array A the corresponding element of array B, and to store the result into the
corresponding element of another array C that will be stored into the data segment starting at
offset 0140 . That means C[i] = A[i] - B[i].
6.6 Executing a Debug Program
This section provides the step-by-step procedures to assemble and execute
Debug programs: the first procedure which is described in Figure 6.9 is used
for programs without any reference to memory locations whereas the second
which is described in Figure 6.10 is used for programs with references to
memory locations. The program defined in Figure 6.1 is used to illustrate the
first procedure and the program defined in Figure 6.8 is used to illustrate the
second one.
Figure 6.9 Step-by-Step Procedure to assemble and execute a Debug program
without any reference to memory locations.
Step 1: At the MS-DOS prompt, execute Debug
C:\WINDOWS>DEBUG
-
Step 2: At the Debug prompt, assemble the instructions of your program starting at offset 0100.
-A 100
0D87:0100 MOV AX, 6 ; AX = 6
0D87:0103 SUB AX, 0A ; AX = 6 - 10
0D87:0106 ADD AX, -0F ; AX = 6 - 10 + (-15)
0D87:0109 ADD AX, 14 ; AX = 6 - 10 + (-15) + 20
0D87:010C SUB AX, -7 ; AX = 6 - 10 + (-15) + 20 - (-7)
0D87:010F MOV DX, AX ; DX = AX
0D87:0111 INT 20
0D87:0113
176
© 2015 Gilbert Ndjatou
Step 3: After you have entered the last instruction of the program, press the ENTER key to return
to the Debug prompt.
-
Step 4: disassemble the instructions of your program (from the memory locations where you have
entered them in Step 2).
-U 100 112
0D87:0100 B80600 MOV AX,0006
0D87:0103 2D0A00 SUB AX,000A
0D87:0106 05F1FF ADD AX,FFF1
0D87:0109 051400 ADD AX,0014
0D87:010C 2DF9FF SUB AX,FFF9
0D87:010F 89C2 MOV DX,AX
0D87:0111 CD20 INT 20
-
Step 5: Display the contents of the registers:
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0100 NV UP EI PL NZ NA PO NC
0D87:0100 B80600 MOV AX,0006
-
Step 6: Trace the execution of the program starting at offset 0100:
-T=100
AX=0006 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0103 NV UP EI PL NZ NA PO NC
0D87:0103 2D0A00 SUB AX,000A
-T
AX=FFFC BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0106 NV UP EI NG NZ AC PE CY
0D87:0106 05F1FF ADD AX,FFF1
-T
AX=FFED BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0109 NV UP EI NG NZ NA PE CY
0D87:0109 051400 ADD AX,0014
-T
AX=0001 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=010C NV UP EI PL NZ AC PO CY
0D87:010C 2DF9FF SUB AX,FFF9
-T
AX=0008 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=010F NV UP EI PL NZ AC PO CY
0D87:010F 89C2 MOV DX,AX
177
© 2015 Gilbert Ndjatou
-T
AX=0008 BX=0000 CX=0000 DX=0008 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0111 NV UP EI PL NZ AC PO CY
0D87:0111 CD20 INT 20
-G
Program terminated normally
-
Step 7: Identify the result(s) of the program (in registers or in memory).
-R
AX=0008 BX=0000 CX=0000 DX=0008 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0111 NV UP EI PL NZ AC PO CY
0D87:0111 CD20 INT 20
-
Figure 6.10 Step-by-Step Procedure to assemble and execute a Debug program
with references to memory locations.
Step 1: At the MS-DOS prompt, execute Debug
C:\WINDOWS>DEBUG
-
Step 2: At the Debug prompt, assemble the instructions of your program starting at offset 0100.
-A 100
0D87:0100 MOV CX, 5 ;LOOP 5 TIMES
0D87:0103 MOV SI, 0 ; INITIALIZE INDEX TO 0
0D87:0106 MOV AX, 120[SI] ; AX = A[SI]
0D87:010A ADD AX, 19 ; AX = A[SI] + 25
0D87:010D MOV 130[SI], AX ; B[SI] = A[SI] + 25
0D87:0111 ADD SI, 2 ; SI = SI + 2
0D87:0114 LOOP 106 ; IF CX <> 0 BRANCH BACK
0D87:0116 INT 20
0D87:0118
Step 3: After you have entered the last instruction of the program, press the ENTER key to return
to the Debug prompt.
-
178
© 2015 Gilbert Ndjatou
Step 4: disassemble the instructions of your program (from the memory locations where you have
entered them in Step 4).
-U 100 117
0D87:0100 B90500 MOV CX,0005
0D87:0103 BE0000 MOV SI,0000
0D87:0106 8B842001 MOV AX,[SI+0120]
0D87:010A 051900 ADD AX,0019
0D87:010D 89843001 MOV [SI+0130],AX
0D87:0111 83C602 ADD SI,+02
0D87:0114 E2F0 LOOP 0106
0D87:0116 CD20 INT 20
Step 5: Define the memory locations that correspond to the operands:
Define the first array then press the Enter key to return to Debug prompt
-A 120
0D87:0120 DW 4, FFFB, 0A, FFF1, 14
0D87:012A
-
Define the second array then press the Enter key to return to Debug prompt
-A 130
0D87:0130 DW 0, 0, 0, 0, 0
0D87:013A
-
Step 6: Display the memory locations that contain the data and identify the different data elements
-D 120 13F
Array A 0D87:0120 04 00 FB FF 0A 00 F1 FF-14 00 BF DB E1 F3 A4 AA ................
Array B 0D87:0130 00 00 00 00 00 00 00 00-00 00 D7 E0 C7 06 CD DF ................
Step 7: Display the contents of the registers:
-R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0100 NV UP EI PL NZ NA PO NC
0D87:0100 B90500 MOV CX,0005 -
Step 8: Trace the execution of the program starting at offset 0100:
-T =100
AX=0000 BX=0000 CX=0005 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0103 NV UP EI PL NZ NA PO NC
0D87:0103 BE0000 MOV SI,0000
-T
AX=0000 BX=0000 CX=0005 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0106 NV UP EI PL NZ NA PO NC
0D87:0106 8B842001 MOV AX,[SI+0120] DS:0120=0004
179
© 2015 Gilbert Ndjatou
-T
AX=0004 BX=0000 CX=0005 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=010A NV UP EI PL NZ NA PO NC
0D87:010A 051900 ADD AX,0019
-T
AX=001D BX=0000 CX=0005 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=010D NV UP EI PL NZ NA PE NC
0D87:010D 89843001 MOV [SI+0130],AX DS:0130=0000
-T
AX=001D BX=0000 CX=0005 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0111 NV UP EI PL NZ NA PE NC
0D87:0111 83C602 ADD SI,+02
-T
AX=001D BX=0000 CX=0005 DX=0000 SP=FFEE BP=0000 SI=0002 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0114 NV UP EI PL NZ NA PO NC
0D87:0114 E2F0 LOOP 0106
-T
AX=001D BX=0000 CX=0004 DX=0000 SP=FFEE BP=0000 SI=0002 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0106 NV UP EI PL NZ NA PO NC
0D87:0106 8B842001 MOV AX,[SI+0120] DS:0122=FFFB
•
•
•
-T
AX=000A BX=0000 CX=0002 DX=0000 SP=FFEE BP=0000 SI=0008 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0114 NV UP EI PL NZ NA PO NC
0D87:0114 E2F0 LOOP 0106
-T
AX=000A BX=0000 CX=0001 DX=0000 SP=FFEE BP=0000 SI=0008 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0106 NV UP EI PL NZ NA PO NC
0D87:0106 8B842001 MOV AX,[SI+0120] DS:0128=0014
-T
AX=0014 BX=0000 CX=0001 DX=0000 SP=FFEE BP=0000 SI=0008 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=010A NV UP EI PL NZ NA PO NC
0D87:010A 051900 ADD AX,0019
-T
AX=002D BX=0000 CX=0001 DX=0000 SP=FFEE BP=0000 SI=0008 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=010D NV UP EI PL NZ NA PE NC
0D87:010D 89843001 MOV [SI+0130],AX DS:0138=0000
180
© 2015 Gilbert Ndjatou
-T
AX=002D BX=0000 CX=0001 DX=0000 SP=FFEE BP=0000 SI=0008 DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0111 NV UP EI PL NZ NA PE NC
0D87:0111 83C602 ADD SI,+02
-T
AX=002D BX=0000 CX=0001 DX=0000 SP=FFEE BP=0000 SI=000A DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0114 NV UP EI PL NZ NA PE NC
0D87:0114 E2F0 LOOP 0106
-T
AX=002D BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=000A DI=0000
DS=0D87 ES=0D87 SS=0D87 CS=0D87 IP=0116 NV UP EI PL NZ NA PE NC
0D87:0116 CD20 INT 20
-G
Program terminated normally
Step 9: Dump the memory locations that contain the data and Identify the result(s) of the program
(in registers or in memory).
-D 120 13F
Array A 0D87:0120 04 00 FB FF 0A 00 F1 FF-14 00 BF DB E1 F3 A4 AA ................
Array B 0D87:0130 1D 00 14 00 23 00 0A 00-2D 00 D7 E0 C7 06 CD DF ....#...-.......
-
In the debugging sessions provided in Figure 6.9 and Figure 6.10, the
descriptions of the steps are in italic and the commands or the entries typed
by the user are in bold. Notice that after you disassemble the instructions of
a program, you must check to make sure that the unassembled instructions
correspond to the instructions that you assembled in step 2. Also, after you
dump the contents of memory locations containing the data elements of your
program, you must check to make sure that the displayed data elements
correspond to those that were entered in memory.
You may notice in Figure 6.10 that in a debugging session, the contents
of a memory location operand are displayed to the right of the instruction in
which it is referenced. After the execution of an instruction, you may also
check the contents of memory locations before you continue the execution
with the next instruction.
181
© 2015 Gilbert Ndjatou
The programs are executed in Figure 6.9 and Figure 6.10 by stepping
through them one instruction at a time. This approach allows you to observe
how individual instructions of a program are executed and to have control
over the execution of your program: partial results can be checked and
verified, and mistakes are detected exactly where they have occurred.
You could also use the T (Trace) command to trace more than one
instruction at a time, or the G (Go) or the P (Proceed) command to execute
more than one instruction at a time. For example, in the debugging sessions
in Figure 6.9 and Figure 6.10, the G (Go) command is used to execute the
interrupt handler for interrupt 20h. The T (Trace) command would have
stepped through the interrupt handler one instruction at a time.
Printing a Debugging Session
One way to print a debugging session is to use the Mark and the Copy Enter
operations provided in a DOS window. The Mark operation is used to mark
a section of a DOS window, and the Copy Enter operation is used to copy the
marked section of a DOS window to the clipboard. These two operations can
be used during a debugging session to copy parts of the debugging session to
the clipboard, and then paste them in a Notepad or a wordprocessor file for
printing at the end of the debugging session. In order to do this, you must
first open a Notepad or a wordprocessor file and then minimize its window
before you run Debug.
Sections of a debugging session are copied to the clipboard and then
pasted to the output file as they appear in the DOS window: after a section of
the DOS window is copied to the clipboard, you will switch to your output
file to paste it into the file, and then switch back to the DOS window to
continue the debugging session. At the end of the debugging session, the
output file is printed using the usual printing procedure of Notepad or the
wordprocessor used to create the file.
182
© 2015 Gilbert Ndjatou
Using the Mark and the Copy Enter Commands in a DOS
Window
To select a section of a DOS window, do the following:
S click the MS-DOS prompt icon on the title bar to access a drop down
menus
S select Edit, then Mark from the drop down menus.
S Now use the mouse to highlight the section of the window that you want
to select: double click at one end of the window section that you want to
select, and then drag the mouse diagonally to the other end.
To copy the selected section of the window to the clipboard, press the
ENTER key or do the following:
S click the MS-DOS prompt icon on the title bar to access the drop down
menus.
S select Edit, then Copy Enter from the drop down menus.