Integer Manipulation. and Iteration Instructions

Chapter 6 Integer Manipulation and Iteration Instructions This chapter discusses some integer manipulation and iteration instructions available on th...
Author: Doris Phillips
6 downloads 0 Views 200KB Size
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.

© 2015 Gilbert Ndjatou

135

136 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.

© 2015 Gilbert Ndjatou

137 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

© 2015 Gilbert Ndjatou

CX

AX

Before execution:

F1F2

000A

After execution:

000A

000A

138 e)

MOV [DS:200h] , BX Memory locations

Register

0200

0201

BX

Before execution:

F1

F2

000A

After execution:

0A

00

000A

Offset:

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:

© 2015 Gilbert Ndjatou

139 syntax:

XCHG destination1, destination2

operation:

destination1

= destination2

destination2

= destination1

and

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:

© 2015 Gilbert Ndjatou

0200

0201

BX

Before execution:

F1

F2

000A

After execution:

0A

00

F2F1

140 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:

BX:

0002

Contents:

CX:

0003

0120 0A

0121 0B

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.

© 2015 Gilbert Ndjatou

141 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: © 2015 Gilbert Ndjatou

unchanged

142 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

© 2015 Gilbert Ndjatou

DX

AX

Before execution:

A0B0

A123

After execution:

FFFF

A123

143

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.

© 2015 Gilbert Ndjatou

144 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

e) ADD

CX

AX

Before execution:

0004

000B

After execution:

000F

000B

[DS:200h] , BX Memory locations Register Offset:

f) ADD

0200

0201

BX

Before execution:

04

00

000B

After execution:

0F

00

000B

AH , [DS:200h] Memory locations Register Offset:

© 2015 Gilbert Ndjatou

0200

AH

Before execution:

0B

04

After execution:

0B

0F

145 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:

© 2015 Gilbert Ndjatou

0200

0201

Before execution:

09

00

After execution:

04

00

146 c) SUB BYTE PTR [DS:200h] , 5 Memory locations Offset:

0200

Before execution:

09

After execution:

04

d) SUB CX , AX Registers

e) SUB

CX

AX

Before execution:

000B

0004

After execution:

0007

0004

[DS:200h] , BX Memory locations Offset:

f) SUB

Register

0200

0201

BX

Before execution:

0B

00

0004

After execution:

07

00

0004

AH , [DS:200h] Memory locations Offset:

Register

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.

© 2015 Gilbert Ndjatou

147 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.

© 2015 Gilbert Ndjatou

148 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

Operation:

same as for IMUL instructions

or MUL source-8

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. © 2015 Gilbert Ndjatou

149

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

b) IMUL CX

AX

BX

Before execution:

A1B2 0005

0002

After execution:

0000

0002

000A

Result =

0000 000A

Result =

FFFF FFF6

Result =

000A

; 0005 * FFFE (decimal 5 * -2) Registers DX

c) IMUL BL

AX

CX

Before execution:

A1B2 0005

FFFE

After execution:

FFFF

FFFE

FFF6

; 05 * 02 (decimal 5 * 2) Registers

d) IMUL CL

AX

BX

Before execution:

1B05

2C02

After execution:

000A

2C02

; 05 * FE (decimal 5 * -2) Registers

© 2015 Gilbert Ndjatou

AX

CX

Before execution:

1B05

2CFE

After execution:

FFF6

2CFE

Result:

FFF6

150 e) IMUL WORD PTR [DS:200h]

; 0005 * 0002

Memory locations Registers Offset:

0200

0201

DX

Before execution:

02

00

A1B2 0005

After execution:

02

00

0000

f)

AX

IMUL BYTE PTR [DS:200h]

000A

Result:

0000 000A

; 05 * FE

Memory locations Registers Offset:

0200

AX

Before execution:

FE

1B05

After execution:

FE

FFF6

Example 6.7

Result:

FFF6

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

0002

b) MUL CX

000A

Result =

0000 000A

Result =

0004 FFF6

; 0005 * FFFE (decimal 5 * 65534) Registers DX

AX

CX

Before execution:

A1B2 0005

FFFE

After execution:

0004

FFFE

© 2015 Gilbert Ndjatou

FFF6

151 c) MUL BL

; 05 * 02 (decimal 5 * 2) Registers AX

BX

Before execution:

1B05

2C02

After execution:

000A

2C02

d) MUL CL

Result =

000A

Result =

04F6

; 05 * FE (decimal 5 * 254) Registers AX

CX

Before execution:

1B05

2CFE

After execution:

04F6

2CFE

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.

© 2015 Gilbert Ndjatou

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 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. © 2015 Gilbert Ndjatou

153 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 16bit 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.

© 2015 Gilbert Ndjatou

154

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: b) IDIV CX

0003 (decimal 3) Quotient:

0002

(Decimal 2)

; 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:

© 2015 Gilbert Ndjatou

03 (decimal 3)

Quotient: 02

(Decimal 2)

155 e) IDIV WORD PTR [DS:200h]

; 0000 000B ÷ 0004 (decimal 11 ÷ 4)

Memory locations Offset:

Registers

0200

0201

DX

AX

Before execution:

04

00

0000

000B

After execution:

04

00

0003

0002

Remainder:

0003 (decimal 3) Quotient: 0002

f) IDIV BYTE PTR [DS:200h]

Example 6.9

Registers

0200

AX

Before execution:

04

000B

After execution:

04

0302

Remainder:

2)

; 000B ÷ 04 (decimal 11 ÷ 4)

Memory locations Offset:

(Decimal

03 (decimal 3)

Quotient: 02

(Decimal 2)

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:

© 2015 Gilbert Ndjatou

0003 (decimal 3) Quotient:

0002

(Decimal 2)

156 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. © 2015 Gilbert Ndjatou

157 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

Program using 16-bit division

MOV BX , 4

; BX = 4

MOV BL , 4

; BL = 4

MOV AX , 23

; AX = 35

MOV AX , 23

; AX = 35

MOV DX, 0

; (DX - AX) = 35

DIV BL

; AH = remain., AL = quot.

DIV BX

; DX = remain., AX = quot.

INT

INT

20

© 2015 Gilbert Ndjatou

20

158

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

Program using 16-bit division

MOV BX , 4

; BX = 4

MOV BL , 4

; BL = 4

MOV AX , -23

; AX = -35

MOV AX , -23

; AX = -35

CW D

; (DX - AX) = -35

IDIV BL

; AH = remain., AL = quot.

IDIV BX

; DX = remain., AX = quot.

INT

INT

20

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 SUB © 2015 Gilbert Ndjatou

; (DX AX) = 5 * 12 CX, AX

; CX = 2 - 5 * 12

159 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 INT

; copy the result to DX

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 = n + m

AX, [DS:130]

; then perform the division ; (DX, AX) = n + m

CWD IDIV

WORD PTR [DS:130] ; AX = quotient of (n + m) / m

SUB

CX, AX

MOV DX, CX INT

© 2015 Gilbert Ndjatou

20

; CX = n + m * n - (n + m) / m ; copy the result to DX

160

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). © 2015 Gilbert Ndjatou

161 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:

© 2015 Gilbert Ndjatou

162 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

b) INC BYTE PTR

Before execution:

0009

After execution:

000A

[200h] Memory locations Offset:

c) DEC

0200

Before execution:

05

After execution:

06

BL Registers BL

© 2015 Gilbert Ndjatou

Before execution:

0A

After execution:

09

163 d) DEC WORD PTR [200h] Memory locations Offset:

e) NEG

0200

0201

Before execution:

0B

00

After execution:

0A

00

AX Registers AX

f) NEG BYTE PTR

Before execution:

0001

After execution:

FFFF

[200h] Memory locations Offset:

6.4

0200

Before execution:

FE

After execution:

02

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:

© 2015 Gilbert Ndjatou

none of the flags is affected.

164 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. M emory Locations at Offset:

Inst. #

AL

BX

CX

?

?

?

?

0200

0201

0202

?

?

?

00 03

?

?

?

Offset

Instructions

0100

MOV

CX, 3

1

?

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

© 2015 Gilbert Ndjatou

165 M emory Locations at Offset:

Inst. #

BX

CX

0200

0201

0202

0204

?

?

06

00

0A

00

00 02

06

00

0A

00

Offset

Instructions

0100

MOV

CX, 2

1

0103

MOV

BX, 200

2

02 00

00 02

06

00

0A

00

0106

ADD

W ORD 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 eth power of n, ne. Assume that e > 0 and that e and n are such 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 n1, and after the second iteration, it will contain n2, . . . , and after the eth iteration, it will contain ne. In order to use the LOOP instruction to accomplish this, you must first load e into register CX. The desired algorithm is described in pseudocode as follows:

© 2015 Gilbert Ndjatou

166 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 ne and store the result at offset 0140. e > 0 and e and n are such that the result is a word. offset

Instructions

Remarks

0100

MOV CX , [DS:120]

; repeat e times

0104

MOV AX , 1

0107

IMUL WORD PTR [DS:130]

010B

LOOP 107

010D

MOV [DS:140] , AX

0110

INT

20

0120

DW

4

; exponent

0130

DW

0C

; number

0140

DW

0

; reserved for the result

; (DX, AX) = AX * n

; if CX > 0 jump to 0107; otherwise continue ; store the result

; ; data

© 2015 Gilbert Ndjatou

167

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:

© 2015 Gilbert Ndjatou

168 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.

© 2015 Gilbert Ndjatou

169 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. © 2015 Gilbert Ndjatou

170 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

; AX = average

0116

MOV [DS:130], AX ; store the result

011A

INT

BX 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. © 2015 Gilbert Ndjatou

171 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.

© 2015 Gilbert Ndjatou

172

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

0103

MOV AX, 0

0106

MOV DI, 0

0109

ADD

AX, [DI + 120] ; AX ² AX + 120[DI]

010C

ADD

DI, 2

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

; AX = average

0117

MOV [DS:130], AX ; store the result

011B

INT

BX

; repeat 5 times ; DI holds the relative position of the first element ; DI holds relative position of next element

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.

© 2015 Gilbert Ndjatou

173 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.

© 2015 Gilbert Ndjatou

offset

Instructions

0100

MOV CX, 5

; loop 5 times

0103

MOV SI, 0

; initialize index to 0

174 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-theloop 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 5th power of this integer value and to store the result in the data segment at offset 0130. 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.

© 2015 Gilbert Ndjatou

175 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 1:

Step-by-Step Procedure to assemble and execute a Debug program without any reference to memory locations.

At the MS-DOS prompt, execute Debug C:\W INDOW S>DEBUG -

Step 2:

At the Debug prompt, assemble the instructions of your program starting at offset 0100.

-A 100 0D87:0100 M OV 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 M OV DX, AX

; DX = AX

0D87:0111 INT 20 0D87:0113

© 2015 Gilbert Ndjatou

176 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

© 2015 Gilbert Ndjatou

MOV

DX,AX

177 -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 1:

Step-by-Step Procedure to assemble and execute a Debug program with references to memory locations. At the MS-DOS prompt, execute Debug C:\W INDOW S>DEBUG -

Step 2:

At the Debug prompt, assemble the instructions of your program starting at offset 0100. -A 100 0D87:0100 M OV CX, 5

;LOOP 5 TIM ES

0D87:0103 M OV SI, 0

; INITIALIZE INDEX TO 0

0D87:0106 M OV AX, 120[SI]

; AX = A[SI]

0D87:010A ADD AX, 19

; AX = A[SI] + 25

0D87:010D M OV 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. -

© 2015 Gilbert Ndjatou

178 Step 4:

disassemble the instructions of your program (from the memory locations where you have entered them in Step 4). -U 100 117

Step 5:

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

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

Step 8:

MOV

CX,0005

-

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

© 2015 Gilbert Ndjatou

MOV

AX,[SI+0120]

DS:0120=0004

179 -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

© 2015 Gilbert Ndjatou

MOV

[SI+0130],AX

DS:0138=0000

180 -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.

© 2015 Gilbert Ndjatou

181 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.

© 2015 Gilbert Ndjatou

182 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.

© 2015 Gilbert Ndjatou