Computer System Organization W Assembly Language Books
Computer System Organization W Assembly Language Books
Preface
Chapter 1: Introduction 1
2.0 Introduction 9
2.1 Address Bus / Data Bus / Control Bus 9
2.2 Bus Cycles 10
2.3 8086/8088 Microprocessor Hardware Configuration 10
2.4 Internal Architecture of the 8088 Microprocessor 11
2.5 Software Architecture of the 8088 Microprocessor 12
2.6 Memory Address Space 13
2.7 Segment Register and Memory Segmentation 15
2.8 Instruction Pointer 18
2.9 Pointer Register 19
2.10 Index Registers 19
2.11 Data Registers 19
2.12 Status Registers 20
More Points to Ponder 22
3.0 Introduction 24
3.1 Register Addressing Mode 25
3.2 Immediate Addressing Mode 25
3.3 Direct Addressing Mode 26
3.4 Register Indirect Addressing Mode 28
3.5 Based Addressing Mode 29
3.6 Indexed Addressing Mode 30
3.7 Based Indexed Addressing Mode 31
More Points to Ponder 34
4.0 Introduction 37
4.1 Data Transfer Instructions 37
4.1.1 MOV 37
4.1.2 XCHG 39
4.1.3 LEA 41
4.1.4 XLAT 42
5.0 Introduction 51
5.1 Unsigned Integer 51
5.2 Signed Integer 51
5.3 Binary-Coded Decimal (BCD) 52
5.4 Packed Decimal (or Packed BCD) 53
5.5 Unpacked Decimal (or Unpacked BCD) 53
5.6 Overflow Flag 53
5.7 Checking for Overflow for Unsigned and Singed Integer 54
5.8 Sign Extension 55
5.9 Addition Instructions 55
5.9.1 ADD 57
5.9.2 ADC 58
5.9.3 DAA 59
5.9.4 AAA 60
5.10 Subtraction Instructions 61
5.10.1 SUB 61
5.10.2 SBB 62
5.10.3 DEC 63
5.10.4 NEG 64
5.10.5 DAS 65
5.10.6 AAS 66
5.11 Multiplication Instructions 68
5.11.1 MUL 68
5.11.2 IMUL 69
5.11.3 AAM 70
5.12 Division Instructions 70
5.12.1 CBW 70
5.12.2 CWD 71
5.12.3 DIV 72
5.12.4 IDIV 73
5.12.5 AAD 74
5.13 Using Arithmetic Instructions in Assembly Language Program 75
More Points to Ponder 78
6.0 Introduction 81
6.1 Compare Instruction 81
6.1.1 CMP 81
6.2 Unconditional Transfer 82
6.2.1 JMP 82
6.3 Conditional Transfer 86
6.3.1 JCC 86
6.4 Iteration Controls 88
6.4.1 LOOP 88
Chapter 11: The 8088 Instruction Set VIII – String Instructions 145
Most of the computers that we are familiar with use the Von Neumann Architecture. Sometimes it is called
the Stored Program Architecture or Fetch, Decode, and Execute Architecture. The Von Neumann Architecture has the
following characteristics:
These three basic hardware subsystems are interconnected by three buses – the Address Bus, Data Bus, and
the Control Bus.
b. Program and data are stored in the main memory and not in the CPU. That is why it is also called Stored
Program Architecture.
c. Instructions in the main memory are fetched, decoded and executed sequentially.
Figure 1.1
Von Neumann Architecture
Not all computers use the Von Neumann Architecture. Some of the non-Von Neumann Architecture are
processor array architecture, multiprocessor architecture, dataflow architecture and neutral network architecture.
Assembly Language was once the only language available for computers. But currently, there are many high-
level languages (e.g. Pascal, Visual Basic, etc.) and more and more people are using them. Be that as it may, assembly
language is still very much alive. This is because of its following advantages over high-level language:
a. Compact Code.
Programs are executed in their native machine language format. Programs written in high-level
language should still be compiled and translated to machine language. But most compilers are not optimized
to generate compact code. Also, most of the pre-defined functions are compiled together with the program
even though only one function is needed.
In assembly language, each instruction (called mnemonic) has its equivalent machine language code
(called opcode). Each mnemonic is translated directly into its opcode equivalent resulting in a more compact
code.
b. Speed.
This is directly related to compact code. The shorter the code, the shorter the execution time of the
program.
c. Flexible.
Assembly language does not constrain the programmer to follow a certain programming convention
(i.e., modularity) nor a rigid coding constraint (i.e., the called routine should be placed before the calling
routine).
On the other hand, high-level language has the following advantages over assembly language:
a. Easy to learn.
Assembly language mnemonics are more cryptic than high-level language instructions.
b. Predefined Functions.
Most high-level languages provide many predefined functions and subroutines, thereby simplifying
programming tasks.
c. Portability.
Assembly Language is specific towards a certain processor. As an example, an assembly language-based
program written in Apple Macintosh using a Motorola 69030 processor cannot be ported directly to an IBM PC
using Intel 80386 processor.
Application programs are becoming more and more complex and are now pushing the high-level language to
its limit. High-level language programmers currently use assembly language-based subroutines to augment the
capabilities of the high-level language.
Figure 1.2 illustrates the Pascal program of “Hello, World!”, while Figure 1.3 illustrates its assembly language
equivalent.
Program Hello:
begin
writeIn (‘Hello, World!’);
end.
Figure 1.2
Pascal program equivalent of “Hello, World!”
Computer System Organization w/ Assembly Language 7
title Hello
dosseg
.model SMALL
.stack 100h
.data
GREET db ‘Hello, World!’, 13,10,’$’
.code
BEGIN:
mov ax,@data
mov ds, ax
mov es, ax
lea dx, [GREET]
mov ah, 09h
int 21h
mov al, 00h
mov ah, 4Ch
int 21h
end BEGIN
Figure 1.3
Intel 8088 based assembly language program
Equivalent of “Hello, World!”
Each new generation of computer is spurred by the advancement of hardware technology – from the primitive
mechanical devices to the complex Very Large Scale Integration (VLSI) chip. Figure 1.4 illustrates the computer
generations.
Figure 1.4
Computer Generations
The history of the electronic digital computer can be traced back as early as the 17th century. During those
times, “computers” were constructed using mechanisms like gears, levels, and pulleys. Some of the highlights during
this era were as follows.
a) The earliest mechanical calculator was built by Blaise Pascal, a French philosopher and scientist, in 1642. It was
essentially a mechanical counter which performed addition and subtraction “automatically”. His machine
included technical innovations such as representing negative numbers in complement and automatic carry
transfer.
b) In 1671, a German philosopher and mathematician named Gottfried Leibniz built a mechanical calculator that
performed multiplication and division, as well as addition and subtraction. His machine was the forerunner of
the four-function calculators.
d) After Babbage, the next major break-through in digital computers was in the 1930s. A German engineer, named
Zuse, built the Z3 in 1941, while an American physicist and mathematics professor at the Harvard University,
named Howard Aiken, built the Mark I in 1944. Both computers were the first operational general-purpose
computers.
Some of the disadvantages of using mechanical and electromechanical devices in computers were as follows:
b) The movement of data by mechanical means (i.e., gears, levers) was cumbersome and unreliable.
What was needed was a device that performed switching functions with no moving parts. This was where the
vacuum tube came in.
The Vacuum tube was invented by Dr. Lee De Forest in 1906. This device ushered in the first generation of
computers. Some of the highlights during this era were as follows:
a) A British mathematician named Alan Turing designed a general-purpose digital computer, known as Automatic
Computer Engine (ACE), in 1950.
b) John Vincent Atanasoff, an Associate Professor of Physics and Mathematics at the Iowa State College, and his
student, Clifford Berry, designed and built a computer known as the Atanasoff-Berry Computer (ABC) in 1939.
c) Professor Atanasoff never filed a patent for his machine. That is why the ENIAC (Electronic Numerical
Integrator and Computer) became the first electronic general-purpose digital computer. ENIAC was designed
and built by John W. Mauchly and John Presper Eckert of University of Pennsylvania. The machine was
completed in 1946.
d) John Von Nuemann, a Hungarian mathematician and a consultant of the ENIAC computer, proposed the stored
program concept. This concept was incorporated in the EDVAC (Electronic Discrete Variable Computer)
machine which was designed and built in 1945.
e) In 1946, Von Nuemann and his colleagues designed the IAS (Institute of Advanced Study) computer at the
Princeton Institute of Advanced Studies. The IAS computer became the prototype of all subsequent general-
purpose computers.
f) The year 1950 saw the birth of the computer industry. At that time two companies, IBM and Sperry, dominated
the market.
h) In 1947, John W. Mauchly and John Presper Eckert formed the Eckert-Mauchly Computer Corporation and
introduced the UNIVAC I (Universal Automatic Computer). Their company was later absorbed by Sperry-Rand
Corporation and became the company’s UNIVAC division.
What was needed was a device that was smaller, dissipated less heat than a vacuum tube, but functioned in
the same way. This was where the transistor came in.
The transistor was invented in 1947 at the AT&T Bell Laboratories by William Shockley, John Bardeen, and
Walter H. Brattain. It was a solid-state device because it was made from silicon. This device ushered in the second
generation of computers. Some of the highlights during this era were as follows:
a) The TX-0, an experimental transistor-based computer, was built at the Lincoln Laboratory of MIT in 1953.
b) In 1957, the Digital Electronic Computer (DEC) was formed and it delivered its first computer, the PDP-1. DEC
later on introduced the concept of the minicomputer.
c) Second generation computers ushered in the concept of the computer system. This meant that a number of
computer peripherals (i.e., I/O devices, memory units) could vary in different installations even though the
same basic computer was used. The concept of the computer system was first used in IBM 7094.
a) Transistors were discrete rather than integrated. This meant that the entire manufacturing process of placing
transistors onto the circuit board was expensive, cumbersome, and error-prone.
b) Designing a more powerful computer was becoming more difficult since the number of transistor used was
growing exponentially.
This was where the Integrated Circuits (IC) came in. The IC was invented by Jack S. Kilby of Texas Instrument
and Robert S. Noyce of Fairchild in 1958. The IC concept was an extension of the solid-state concept of the transistor.
In IC, many transistor components could be packed inside a silicon chip whose size was no longer than a fingernail. This
device ushered in the third generation of computers. Some of the highlights during this era were as follows:
a) In 1964, DEC introduced the PDP-8, the industry’s first minicomputer. Minicomputers were essentially much
cheaper and smaller than mainframes.
b) In 1964, IBM, through its System/360, introduced the concept of the family of computers. This meant that each
model within the family ran the same programs but they differed in memory size and speed.
With the advancement of integrated circuits technology, more and more transistor components can be packed
inside an IC. ICs are classified as follows:
The highlight of this era was the development of the microprocessor. In 1971, Marcian E. “Ted” Hoff,Jr. of the
Intel Corporation developed the 4004 – the industry’s first microprocessor. A microprocessor is basically a CPU, but
with all its components placed in a single chip. With the advent of the microprocessor, the microprocessor was born.
Microcomputers are computers that utilize the microprocessor as CPU.
The evolution of the microprocessor can be seen through the number of bits that it processes at one time.
Figure 1.5 illustrates the genealogy of the Intel family of microprocessors.
Figure 1.5
Genealogy of Intel Microprocessor
Figure 2.1
Microcomputer system block diagram
The heart of the microcomputer system is the MPU. The term MPU is sometimes used interchangeably with
the term CPU. But there is a difference between the two. The CPU is usually implemented on a board level where the
components are discrete rather than integrated. This means that it is possible for the arithmetic logic unit (ALU) to be
placed on one circuit board. Whereas the MPU is implemented on a single VLSI chip. Thus, the ALU, CPU, register, and
other components are all packed inside one integrated circuit. That is why the MPU is sometimes referred to as CPU-
on-a-Chip.
A microprocessor communicates externally (i.e., with the memory or I/O devices) via a bus. A bus is a set of
parallel wires or lines. There are three types of bus: address bus, data bus, and control bus.
The address bus is used to select the desired memory or I/O devices by providing a unique address that
corresponds to one of the memory or I/O devices. It is unidirectional (i.e., from the microprocessor to the external
devices). If a microprocessor has 20 address bus, it means that it could access up to 1,048,576 (2^20) possible address
location.
The data bus is used to transfer data to and from the memory or I/O devices. It is bidirectional.
The control bus is used to carry control signals to and from the memory or I/O devices. For example, some
microprocessors use the RD’ signal to request data either from the memory or from the I/O devices (i.e., memory read
or I/O read). It is bidirectional.
All activities in the microprocessor are synchronized via bus cycles (or machine cycles). During each bus cycle,
an instance of an activity is being performed. For example, the microprocessor needs three bus cycles to fetch a data
from the memory. During the first cycle, the microprocessor sends the address to the address bus. On the second cycle,
the microprocessor sends the read signal to the control bus, and on the third cycle, the memory sends data to the data
bus.
How long is one cycle? The length of a bus cycle is relative to the clock rate of the microprocessor. If a
microprocessor has a clock rate of 5MHz, this means that it can handle 5,000,000 bus cycles in one second. Thus, each
bus cycle is 200 nanoseconds long (i.e., 1/5,000,000).
A nanosecond is a billionth of a second (i.e., 10^9). How fast is a nanosecond? Just imagine that an
electrical signal travels the distance of 11.8 inches in one nanosecond!
In the previous example, a microprocessor with a clock rate of 5MHz will take up 600 nanoseconds to fetch a
data from the memory (i.e., 3 bus cycles * 200 nanoseconds).
Points to ponder
In the example above, if the clock rate of the microprocessor is increased to 66MHz, how long will it take to
fetch a data from the memory?
Registers are temporary storage areas for instructions or data. They are found inside the MPU.
The address bus of the 8086 microprocessor is 20 bits in length. This means that it is capable of accessing up to
1,048,576 (2^20) possible address locations.
The 8088 microprocessor is the same as the 8086 microprocessor except for one aspect. For the 8088, it only
has an 8-bit data bus. This means that it communicates with memory or I/O devices 8 bits of data at one time. That is
why the 8088 is also known as the 8-bit external bus version of the Intel’s 8086 family of 16-bit microprocessors.
The implication of having an 8-bit data bus means that, in order for the 8088 to process 16 bits of data, it needs
to fetch the (16 bit) data twice. Whereas, for the 8086, it needs to fetch that (16 bit) data only once.
The idea of introducing an 8-bit external bus version of 8086 is to provide compatibility with existing I/O
devices. This is because the majority of the I/O devices during time could only support 8-bit data.
The technical name for the 8088 microprocessor is iAPX88 (Intel Advanced Processor Architecture 88). It is
manufactured using High Performance Metal Oxide Semiconductor (HMOS) technology. It has more than 29,000
transistor components, making it a VLSI chip. The 8088 utilizes a 40-pin Dual Inline package (DIP) and a multiplexed pin
layout scheme (see Figure 2.2).
The multiplexed pin layout scheme is a scheme in which a pin carries one type of signal during one time period
and a different signal during another. Though the 8088 needs 20 pins for address bus, 8 pins for data bus, 30 pins for
control bus and 3 pins for power (61 pins total), it is packaged with 40 pins only. But, with the multiplexed pin layout
scheme, it is possible for the 8088 microprocessor to accommodate 61 pins into the 40-pin package.
In Figure 2.2, AD7 is a multiplexed pin. At one point, it functions as an address bus and, at other times,
it functions as a data bus.
GND 1 40 Vcc
A14 2 39 A15
A13 3 38 A16/S3
A12 4 37 A17/S4
A11 5 36 A18/S5
A10 6 35 A19/S6
A9 7 34 SS0’/HIGH
A8 8 33 Mn/Mx
AD7 9 32 RD
AD6 10 31 HOLD (RQ’/GT0’)
AD5 11 30 HLDA (RQ’/GT1’)
AD4 12 29 WR’ (LOCK’)
AD3 13 28 IO/M’ (S2’)
AD2 14 27 DT/R’ (S1’)
AD1 15 26 DEN’ (S0’)
AD0 16 25 ALE (QS0)
NMI 17 24 INTA’ (QS1)
INTR 18 23 TEST’
CLK 19 22 READY
GND 20 21 RESET
Figure 2.2
Pin layout of the 8088 microprocessor
The task of the BIU is to fetch instructions or data from the memory and transfer data from the internal registers
to the memory. On the other hand, the task of the EU is to decode the instructions and execute them.
8086 and 8088 differ only in the BIU. The BIU of the 8086 works on a 16-bit address bus, while that of
the 8088 on an 8-bit address bus.
Since the BIU and the EU function independently of each other, it is possible for the EU to decode and execute
the current instruction, while the BIU is already fetching the next instruction. In fact, an instruction pre-fetch queue is
used in conjunction with BIU. An instruction pre-fetch queue is a first-in-first-out (FIFO) storage area that allows from
4 bytes (8088) to 6 bytes (8086) of instructions to be pre-fetched. Thus, fetch and execute phases can overlap, thereby
speeding up execution. This technique is called pipelining.
The software architecture of the 8088 is illustrated using the software model (see Figure 2.4). In this model,
the 8088 is viewed in terms of internal registers and their relationship with the external memory.
All address in the memory are expressed in hexadecimal unless stated otherwise.
The model also includes the external memory, which is viewed as 1,048,576 bytes (00000h to FFFFFh) of
memory address space.
The succeeding sections discuss the different elements of the software model in detail.
A word can be stored at even or odd address boundaries. The Least Significant Bit (LSb) of the address
determines the type of word boundary. If this bit is 0, then the word is at an even-address boundary.
Example:
The word data 5502h is located at address 00724. The LSB of the word data, 02h, is located at a lower address
(00724), while the MSB of the word data, 55h, is located at a higher address (00725). Since the LSb of the address is 0
(i.e., 00724 in binary is 0000 0000 0111 0010 0100), the word data is located at an even-address boundary.
Besides byte and word data, the 8088 could also handle double words. A double word consists of four
consecutive bytes of data. The lower-addressed byte is the Least Significant Byte (LSB) of the double word, while the
higher-address byte is the Most Significant Byte (MSB). As with a word, a double word can also be stored at an even
or odd address boundary. Double words are usually used as b (i.e., address).
Example:
The double word data 3B4C0065h is located at address 01125. The LSB of the double word data, 65h, is located
at a lower address (01125), while the MSB of the double word data, 3Bh, is located at a higher address (01128). Since
the LSb of the address is 1 (i.e., 01125 in binary is 0000 0001 0001 0010 0101), the double word is located at an odd-
address boundary.
This problem is resolved using memory segmentation. In this scheme, programs views memory space as
composed of many logical partitions called segments. A segment is defined as a logical unit of memory that is 64-kbytes
(65,536 bytes) long. Each of this 64-kbytes segment should be in contiguous memory locations. Each segment is
assigned a base address that identifies its starting point (the segment’s lowest-address memory location) and an offset
address to point to memory locations within the segment.
The offset address is relative to the base address. Therefore, it could only point to memory locations within a
segment. To access the next segment, the base address should be modified to point to the next segment. By combining
the base address and the offset address, it is now possible to access the entire 1-Mbyte of memory locations.
All segments should start on a 16-byte address boundary (i.e., paragraph boundary). This means that the last
hexadecimal digit of the physical address should be 0. Segments maybe adjacent, disjoint, partially overlapped, or fully
overlapped.
There are a total of 65,536 (64-kbytes) of possible segments in the 1-Mbyte memory space.
Points to Ponder
Based on Figure 2.6, give the relationship of segments A, B, C, D, E, F, and G to one another.
Explain why there are 65,536 (64 Kbytes) possible segments in the 1-Mbyte memory space.
Explain why there are 16 contiguous segments in the 1-Mbyte memory space.
Only four of the segments can be active at one time. Active segment means that the MPU could access
instructions or data in that segment. These four active segments are the code segment, stack segment, data segment,
and extra segment. Code segment contains the program code (instruction), stack segment contains the stack, data
segment, and extra segment contain the data. Segment registers contain the base address of the active segments. Thus,
CS register contains the base address of the code segment, DS register contains the base address of the data segment,
SS register contains the base address of the stack segment, and the ES register contains the base address of the extra
segment. By changing the value of the segment register, the MPU can access instruction or data in other segments.
Since a segment always starts at a paragraph boundary, the segment register automatically represents
the paragraph boundary already. This means that if SS register contains the value of 1234h, it
automatically refers to address 12340h.
In Figure 2.7, the SS register points to base address of 05000, both DS and SS register point to base address
16000 while CS register points to base address 21450. One could also observe that the data segment and the extra
segment fully overlapped each other.
Figure 2.6
Memory Segmentation
The programmer uses the logical address notation instead of the physical address notation. A physical address
is a 20-bit value that identifies the individual byte locations in the memory space. Whereas, a logical address consists
of a segment base value (the segment register) and an offset value (the offset register). The format of the logical address
is XXXX:YYYY, where XXXX is the value of the segment register and YYYY is the value of the offset register. In the
previous example, the logical address is 2145:0002 (i.e., CS:IP).
To convert a logical address into its equivalent physical address, just append a 0 on the segment register value,
then add the offset register value. The value should all be in hexadecimal. As stated earlier, since the segment register
value already represents the paragraph boundary, a 0 is just appended to the segment register value.
Example:
Answer: 12344
What would be the offset value required to map to physical address location 01128 if the segment
address is 0100?
Answer: 0128
Note that many logical address can be mapped to the same physical address location in the memory. For
example: 0100:0128, 0000:1128, 0001:1118, 0002:1108, 0101:0118 all map to physical address 01128.
Point to Ponder
Give some more logical address that will map to physical address 01128.
SP and BP usually contain offset address but it can also be viewed as data used in most arithmetic and
logic operations.
SI and DI usually contain offset address but it can also be viewed as data used in most arithmetic and
logic operations.
The four data registers are used in arithmetic and logic operations but the BX register is also used as
offset register for DS and ES registers (i.e., BX contains an offset address).
AX
Accumulator
AH AL
BX
Base
BH BL
CX
Count
CH CL
DX
Data
DH DL
Figure 2.8
General-purpose Data Register
Figure 2.9
Dedicated Register Functions
/ / / / OF DF IF TF SF ZF / AF / PF / CF
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Figure 2.10
Status Register
Status Flags indicate the conditions that are produced as a result of executing an arithmetic or logic instruction.
Thus, these flags are set (1) or reset (0) upon the completion of execution of the instruction.
The following are the status flags, as well as their individual characteristics:
a. Carry Flag (CF). CF is set of there is a carry-out from the most significant bit of the result, or a
borrow-in to the most significant bit of one operand, during the execution of an arithmetic
instruction. Otherwise, CF is reset.
b. Parity Flag (PF). PF is set if the result produced has even parity (i.e., even number of 1’s).
Otherwise, if the result produced has an odd parity, PF is reset.
c. Auxiliary Carry Flag (AF). This is also known as Half-Carry Flag. AF is set if there is a carry-out
from the low nibble to the high nibble of the result, or a borrow-in from the high-nibble to the
low-nibble of one operand. Otherwise, AF is reset.
d. Zero Flag (ZF). ZF is set if the result of the operation is zero. Otherwise, ZF is reset.
e. Sign Flag (SF). The most significant bit of the result is copied to SF. This means that SF is set if
the result is a negative number and reset if the result is a positive number.
Computer System Organization w/ Assembly Language 25
f. Overflow Flag (OF). OF is set if the signed result is out of range. Otherwise, OF is reset.
a. A positive number added to another positive number and the result yielded a positive
number.
b. A negative number added to another negative number and the result yielded a negative
number.
Example:
CF = 0 ZF = 0
PF = 0 SF = 0
AF = 0 OF = 0
Control Flag are used to control the function of the 8088. The following are the control flags and their
characteristics:
a. Trap Flag (TF). If TF is set, the 8088 goes into the single-step mode for debugging.
b. Interrupt Flag (IF). If the IF is set, the 8088 can recognize external maskable interrupt requests.
c. Direction Flag (DF). The value of DF determines the direction in which the string operations will
occur. If DF is set, the string instruction automatically decrements the address. If DF is reset,
the string instruction automatically increments the address.
I. Identification
1. What is the highest address in the 8088’s memory address space? (in hex)
2. What is the lowest address in the 8088’s memory address space? (in hex)
3. The contents of memory location 12724h is 1Fh and that at 12725h is 10h. What is the even-
addressed data word stored at address 12724h?
4. Show how the double word 12345678h will be stored in memory, starting at address 1ABCDh.
5. How much of the 8088’s active memory is available as general-purpose data storage memory?
6. What would be the value of the status flags after this operation: 4Ah + 2Ch?
7. What would be the value of the status flags after this operation: 02h + FEh?
8. If the current values in the code segment register and the instruction pointer are 1234h and 5678h,
respectively, what is the physical address of the next instruction?
9. A data segment is to be located from address D0000h to DFFFFh. What value must be loaded to DS?
10. If the data segment register contains the value found in problem 9, what value must be loaded to DI if
it is to point to a destination operand stored at address D1234h in memory?
a. Internal Registers
b. Part of the Instruction
c. Memory
MOV AX, BX
operands
mnemonic
Figure 3.1
An Example of an 8088 Instruction
Addressing Mode refers to how the 8088 accesses the operands. The seven types of addressing modes are:
There are actually two more other types of addressing mode: String Addressing Mode and Port Addressing
Mode. These two addressing modes will not be discussed in this text.
For the register addressing mode, operands are stored in the registers. For the immediate addressing mode,
operands are stored as part of the instruction. For the rest of the addressing modes, the operands are stored in memory.
For the succeeding sections, all examples will be based on the MOV instruction. The syntax of MOV is: MOV
destination, source (i.e., destination <- source). In Pascal, it is equivalent to destination:=source.
MOV AX, BX
In the example given, the source operand is stored in register BX. The contents of register BX is moved to
register AX (i.e., the destination operand). After execution, the contents of register AX is 4567. Note that the contents
of the source operand remains the same after execution.
a. Operand in the immediate addressing mode could only be used as source operand.
The instruction MOV 1234, AX is considered invalid since the immediate addressing mode is used as the
destination operand.
Figure 3.2
MOV AX, BX
The opcode for MOV AX, 2234 is located at CS:0000 or physical address 01000. The source operand is part of
the instruction and is located 2 bytes away from the opcode (i.e., CS:0002 or physical address 10002). Thus, the effective
address of the source operand is 0002.
The source operand which contains the immediate data 2234 is moved to register AX. After execution, the
register AX contains a value 2234.
For example, in the instruction MOV AX,[0008], the source operand contains the effective address 0008. This
means that the operand is stored at 8 bytes away from the DS register.
In the example given, the source operand contains the effective address. Thus, the EA of the source operand is
1234. This means that the source operand is located at address DS:1234. That value is then moved to register CX. After
execution, the contents of register CX is BEED.
Memory location BETA contains a value of BEED. This value is then copied to register CX. After execution, the
contents of register CX is BEED.
Points to Ponder
If the effective address is stored in BP, it is with respect to the SS register, for the rest (i.e., SI, DI, BX), it is with
respect to the DS register.
Points to Ponder
In the example given, the source operand consists of a label and register BX. The effective address of the label
is computed to be 1234h (i.e., DS:BETA = 03234). The effective address of the source operand is computed to be 2234
(i.e., the sum of the effective address of the label, 1234, and register BX, 1000). Since register BX is used, the effective
address of the source operand is relative to the data segment. The physical address is therefore computed to be 04234
(i.e., DS:2234). The source operand is then moved to register AX. After execution, the contents of register AX is BEED.
Note that after execution, the value of register BX remains the same.
In other literatures, the notation foe based addressing mode could be nay of the following:
In the example given, the source operand consists of a label and register SI. The effective address of the label
is computed to be 1234h (i.e., DS:BETA = 03234). The effective address of the source operand is computed to be 2234
(i.e., the sum of the effective address of the label, 1234, and register SI, 1000). Since the effective address of the source
operand is relative to the data segment, the physical address is therefore computer to be 04234 (i.e., DS:2234). The
source operand is then moved to register AX. After execution, the contents of register AX is BEED. Note that after
execution, the value of register SI remains the same.
Computer System Organization w/ Assembly Language 35
In other literatures, the notation for indexed addressing mode could be any of the following:
In based indexed addressing mode, the operand consists of either a displacement value or a label, either
register SI or DI and either register BX or BP. The effective address of the operand is computed as the sum of the
displacement value or the “effective address” of the label, the contents of either register SI or DI and the contents of
either register BX or BP. On the other hand, the physical address of the operand is obtained by adding the effective
address of the source operand with either the current value in register DS(for BX) or SS(for BP).
In the example given, the source operand consists of a label, register BX and register SI. The effective address
of the label is computed to be 1234h (i.e., DS:BETA = 03234). The effective address of the source operand is computed
to be 4234 (i.e., the sum of the effective address of the label, 1234, register BX, 1000, and register SI, 2000). Since
register BX is used, the effective address of the source operand is relative to the data segment. The physical address is
therefore computed to be 06234 (i.e., DS:4234). The source operand is then moved to register AX. After execution, the
contents of register AX is BEED. Note that after execution, the value of register SI remains the same.
In other literature, the notation for based indexed addressing mode could be any of the following
I. Tracing
The initial contents of the 8088 CPU register and some memory locations are shown below. Each set of
questions is independent of the others, so always refer back to the initial state. All values are in hexadecimal notation.
Your answer should also be in hexadecimal. If there is an invalid syntax in the instruction then write “ERROR”. If answers
cannot be obtained due to lack of given, then write “N/A”.
A. MOV SI, DX
G. MOV GAM[DX], AX
In this text, the discussion of the instruction set will be organized into groups of functionally related
instructions. For this chapter, the discussion will concentrate on data transfer instructions. The remaining instrucitons
will be discussed in the succeeding chapters.
4.1.1 MOV
The MOV instruction transfer a byte or a word from the source operand to the destination
operand. Figure 4.1 illustrates the definition of MOV instruction, while Figure 4.2 illustrates the allowed
operands for it.
Figure 4.1
MOV Instruction
There are some important facts to remember about the MOV instruction. These are as follows:
a. The MOV instruction does not allow both source and destination operands to be of memory addressing
mode at the same time (i.e., no memory to memory transfer). For example, MOV BETA,[SI] is invalid.
b. If the destination operand is a memory addressing mode and the source operand is an immediate
addressing mode, the prefix byte ptr or word ptr should be appended after the MOV instruction to
denote the data size of the immediate operand. Use byte ptr to denote a byte-sized data and word
ptr to denote a word-sized data.
Where:
Register = AX, BX, CX, DX, SI, DI, BP, SP,
AF, BH, CH, DH, AL, BL, CL, DL
Reg16 = AX, BX, CX, DX, SI, DI, BP, SP
Seg-Reg = CS, DS, ES, SS (as source operand);
DS, ES, SS (as destination operand)
Memory = Displacement value or label + [BX/BP] + [SI/DI]
Figure 4.2
Allowed operands for MOV instruction
c. Both source and destination operands should be of the same data size. Thus, MOV AX, CL is invalid
since the source operand is a byte while destination operand is a word.
MOV BETA, AX
In the example given, memory location BETA is the destination operand. This means that the original
value will be overwritten by the source operand (i.e., register AX). After execution, memory location BETA will have a
value of 1234. Note that the source operand remains unaffected after execution (i.e., AX still retains the value of 1234).
4.1.2 XCHG
The XCHG instruction swaps the contents of the source and destination operands. Figure 4.4 illustrates
the definition of XCHG instruction, while Figure 4.5 illustrates the allowed operands for the XCHG instruction.
Figure 4.4
XCHG instruction
Figure 4.5
Allowed operands for XCHG instruction
a. Immediate addressing mode cannot be used with this instruction. This is because the source operand
is also the destination operand and vice versa. Thus, XCHG AX, 1234 is invalid.
b. XCHG instruction does not allow both source and destination operand to be of memory addressing
mode at the same time (i.e., no memory to memory exchange). This means that XCHG BETA, [BX] is
invalid.
c. Both source and destination operands should be of the same data size. The instruction XCHG, AX CL is,
therefore, invalid since the source operand is a byte while the destination operand is a word data.
XCHG BETA, AX
4.1.3 LEA
The LEA instruction is used to transfer the effective address of the source operand to the destination operand.
Compare this with the MOV instruction in which data is transferred from source operand to destination operand. Figure
4.7 illustrate the definition of LEA instruction.
Figure 4.7
LEA instruction
There are some important facts to remember about the LEA instruction. These are as follows:
a. The source operand should always be one of the memory addressing modes, while the destination operand
should always be a 16-bit register.
b. In LEA instruction, the effective address is moved to the destination operand. Therefore, one could view
the destination operand as a pointer.
c. It is recommended, though not necessary, to use register BX, SI, DI, or BP as the destination operand since
these 4 registers could be used as offset register or pointers.
d. The LEA instruction is synonymous to the instruction MOV offset Reg16, EA (example: MOV offset SI,
BETA).
In the example given, the LEA instruction will transfer the effective address of the source operand to register
SI. Therefore, register SI will now contain a value of 0008 after execution.
The XLAT instruction is provided to simplify the implementation of the user-defined look-up table
operation. Figure 4.9 illustrate the definition of XLAT instruction.
Figure 4.9
XLAT instruction
There are some important facts to remember about the XLAT instruction. These are as follows:
a. Before using the XLAT instruction, register BX should point to the beginning of the table while register
AL contains the index to the table. The programming pattern for XLAT is as follows:
In the example given, register BX now points to the start of the translation table (i.e., memory location
BETA), while register AL is the index or the offset value of the translation table. By execution the XLAT instruction,
register AL will now be replaced by the data located at the memory location BETA offset by register AL. After execution,
register AL will have a value of 72.
The LDS instruction transfers a 32-bit pointer from the source operand to the destination operand and
register DS. Figure 4.11 illustrates the definition of LDS instruction.
Figure 4.11
LDS instruction
There are some important facts to remember about the LDS instruction. These are as follows:
a. LDS instruction transfer a 32-bit pointer stored in the memory to the 16-bit register and register DS.
This means that the source operand should be one of the memory addressing modes. The destination
operand is composed of a 16-bit register and register DS.
b. The least significant word of the 32-bit pointer is stored in the 16-bit register, while the most significant
word is stored in the DS register.
In the example given, the 32-bit pointer (i.e., 19721128) is located at memory location BETA. The least
significant word, 1128, is stored in register SI, while the most significant word, 1972, is stored in register DS.
4.1.6 LES
The LES instruction transfers a 32-bit pointer from the source operand to the destination operand and
register ES. Figure 4.13 illustrate the definition of LES instruction.
Figure 4.13
LES instruction
There are some important facts to remember about the LES instruction. These are as follows:
a. LES instruction transfer a 32-bit pointer stored in the memory to the 16-bit register and register ES. This means
that the source operand should be one of the memory addressing modes. The destination operand is composed
of a 16-bit register and register ES.
b. The least significant word of the 32-bit pointer is stored in the 16-bit register, while the most significant word
is stored in the ES register.
c. LES instruction is almost the same as LDS instruction. The only difference lies in the segment register. For LES,
register ES is used, while LDS, register DS is used.
In the example given, the 32-bit pointer (i.e., 19721128) is located at memory location BETA. The least significant word,
1128, is stored in register SI, while the most significant word, 1972, is stored in register ES.
This section will discuss how data transfer instructions are used in assembly language programming
4.2.1 Write an assembly language program that exchanges the contents of byte memory location ALPHA with
byte memory location BETA. Assume register AL is available as temporary register.
Since memory to memory exchange is not possible, a temporary register is needed to facilitate the
exchange. In line 1, the contents of memory location ALPHA is transferred to AL. In line 2, the value of
AL, which originally contains the value of ALPHA, is exchange with BETA. Line 3 is needed since memory
location ALPHA has yet to be updated. The value of AL, which now contains the value BETA, is
transferred to ALPHA.
In this version, instruction LEA is used to initialize register SI and DI as pointers to memory locations
ALPHA and BETA, respectively. This means that [SI] is used to refer to the contents of memory location
ALPHA, while [DI] is used to refer to the contents of memory location BETA. Line 3, 4, and 5 of version
2 are the same of lines 1, 2, and 3 of version 1.
Computer System Organization w/ Assembly Language 50
Name: __________________________________________ Score: __________________
Course & Section: __________________
I. Tracing
The initial contents of the 8088 CPU register and some memory locations are shown below. Each set of
questions is independent of the others, so always refer back to the initial state. All values are in
hexadecimal notation. Your answer should also be in hexadecimal. If there is an invalid syntax in the
instruction, then write “ERROR”. If answer cannot be obtained due to lack of givens, then write “N/A”.
II. Programming
Write an assembly language program to exchange a byte memory location 4 bytes away from memory
location ALPHA, with a byte memory location 3 bytes away from memory location BETA. Assume register BL is
available as temporary register.
Various concepts related to arithmetic operands will be discussed first, after which different arithmetic
instructions will be discussed in detail.
Example:
Example:
Decimal Number 8-bit unsigned integer 16-bit unsigned integer
+25 0001 1001 0000 0000 0001 1001
-25 1110 0111 1111 1111 1110 0111
+128 Overflow 0000 0000 1000 0000
-128 1000 0000 1111 1111 1000 0000
+150 Overflow 0000 0000 1001 0110
-150 Overflow 1111 1111 0110 1010
+32768 Overflow Overflow
-32768 Overflow 1000 0000 0000 0000
BCD uses only 10 out of 16 possible combinations. The following 6 combinations are never used:
1010, 1011, 1100, 1101, 1110,1111.
There are some situations in which arithmetic operations on BCD numbers require some adjustments. This
happens if the result of the operation falls into one of the six unused combinations. The adjustment is done by adding
six to the previous result in order to get the final result.
Figure 5.1
BCD equivalent of decimal digits
Example:
*24 (decimal) + 45 (decimal) = 69 (decimal)
Since none of the nibble in the result has an invalid combinations, the result is correct already.
In this case, the intermediate result contains an invalid combination. Thus, 6 is added to the intermediate
result as part of the adjustment.
For addition and subtraction, it is preferred that the most significant nibble has a value of 3. This because
addition and subtraction operations view unpacked decimals as ASCII numbers (American Standard Code for
Information Interchange).
a. There is a carry from the 2nd to the last bit to the most significant bit but no carry from the most
significant bit to the carry flag bit (i.e., “carry, no carry”).
b. There is no carry from the 2nd to the last bit to the most significant bit but there is a carry from the
most significant bit to the carry flag bit (i.e., “no carry, carry”).
Example:
In this example, overflow flag is set since there is a carry from the 2nd to the last bit to the most significant
bit but no carry from the most significant bit to the carry flag bit (carry, no carry).
In this example, overflow flag is set since there is no carry from the 2nd to the last bit to the most significant
bit but there is a carry from the most significant bit to the carry flag bit (no carry, carry).
In this example, overflow flag is reset since there is no carry from the 2nd to the last bit to the most significant
bit and there is no carry from the most significant bit to the carry flag bit (no carry, no carry).
8088 views numbers as raw binary data. It is up the programmers to interpret the numbers as signed or
unsigned integers.
Example:
In the given example, if the numbers are viewed as signed integers, then the result is not an overflow since
the overflow flag is reset. If the numbers are viewed as unsigned integers, then the result is an overflow since the carry
flag is reset.
Points to Ponder
Why is it that for unsigned integers, carry flag is used to check for “overflow”, while for signed integers,
overflow flag is used to check for “overflow”?
Example:
In the ADD instruction, the source operand is added to the destination operand and the result replaces
the destination operand. Figure 5.2 illustrates the definition of the ADD instruction, while Figure 5.3 illustrate the
allowed operands for the ADD instruction.
Figure 5.2
ADD instruction
Figure 5.3
Allowed operands for ADD and ADC instructions
There are some important facts to remember about the ADD instruction. These are as follows:
a. ADD instruction does not allow both source and destination operands to be of memory addressing
mode at the same time (i.e., no memory to memory addition). For example, ADD BETA, ALPHA is
invalid.
b. As with the MOV instruction, if the destination operand is a memory addressing mode and the source
operand is an immediate addressing mode, the prefix byte ptr or word ptr should be appended after
the ADD instruction to denote the data size of the immediate operand.
c. Both source and destination operands should be of the same data size. For example, ADD CX, DL is
invalid.
d. All status flags are affected after execution.
Q: What will be the value of the different status flags after execution?
A: CF = 0, OF = 0, PF = 1, ZF = 0, AF = 0, SF = 0
Computer System Organization w/ Assembly Language 58
AX = 0001 0001 0001 0001
BX = 0010 0010 0010 0010
_______________________
0011 0011 0011 0011
The original contents of memory location BETA is 6655. Add this value to the immediate data 1234. The result
is stored back to memory location BETA.
In the ADC instruction, the source operand, the destination operand, and the value of carry flag are
added together and the result replaces the destination operand. Figure 5.5 illustrates the definition of the ADC
instruction, while Figure 5.3 illustrates the allowed operands for the ADC instruction.
Figure 5.5
ADC instruction
There are some important facts to remember about the ADC instruction. These are as follows:
a. In ADC instruction, the current value of the carry flag (i.e., add 1 if carry flag is set and 0 if carry flag
is reset) is added together with the source and the destination operand.
b. ADC instruction can be used to write routines to add numbers longer than 16 bits.
c. All important facts mentioned in the ADD instruction also apply for the ADC instruction.
Example:
The initial value of register AX is 0001. After executing the 2nd instruction, register AX contains a value of
0002, and the carry flag is 0. After the 3rd instruction, register AX now contains a value of 0003 (destination operand is
0002, source operand is 0001, and carry flag is 0).
5.9.3 INC
The INC instruction adds 1 to the destination operand. Figure 5.6 illustrates the definition of INC
instruction, while Figure 5.7 illustrates the allowed operands for the INC instruction.
Figure 5.6
INC instruction
Figure 5.7
Allowed operands for INC instruction
There are some important facts to remember about the INC instruction. These are as follows:
Example:
Q: What will be the value of the different status flags after execution?
A: ZF = 1, AF = 1, SF = 0, OF = 0, PF = 1, CF remains unchanged
In this example, register AH is not affected since only register AL is incremented. AH still retains the value of
11, while AL now has a value of 00 (FF + 1).
5.9.4 DAA
The DAA instruction adjust the result of a previous addition of two valid packed decimal operands.
Figure 5.8 illustrates the definition of the DAA instruction.
Figure 5.8
DAA instruction
There are some important facts to remember about the DAA instruction. These are as follows:
Example:
MOV AL, 15
MOV BL, 15
ADD AL, BL
DAA
In the example, the values of AL and BL are viewed as BCD (i.e., packed decimal). Since DAA instruction will
be used to adjust the addition operation, the destination operand of the ADD instruction should be in AL. Prior to DAA,
the value of AL is adjusted to 30h. The operation is as follows:
Since the lower nibble of the intermediate result is greater than 9, DAA adjust the result by adding 6 to the
lower nibble.
5.9.5 AAA
The AAA instruction adjust the result of a previous addition of two valid unpacked decimal operands.
Figure 5.9 illustrates the definition of the AAA instruction.
Figure 5.9
AAA instruction
Example:
In this example, the values of AL and BL are viewed as ASCII numbers (i.e., unpacked decimal). Since the AAA
instruction will be used to adjust the operation, the destination operand of the ADD instruction should be in AL. Prior
to AAA, the value of AL is 6Ah. After the AAA instruction, the value of AL is adjusted to 09h. The operation is as follows:
Since the least significant nibble is not greater than 9 nor the AF = 1, the only adjustment needed is to zero
out the most significant nibble.
In the SUB instruction, the source operand is subtracted from the destination operand and the result
replaces the destination operand. Figure 5.10 illustrates the destination of SUB instruction, while Figure 5.11 illustrates
the allowed operands for the sub instruction.
Figure 5.10
SUB instruction
Figure 5.11
Allowed operands for SUB and SBB instructions
There are some facts to remember about the SUB instruction. These are as follows:
a. The SUB instruction does not allow both source and destination operands to be of memory
addressing mode at the same time (i.e., no memory to memory subtraction). For example, SUB BETA,
ALPHA is invalid.
b. As with the MOV instruction, if the destination operand is a memory addressing mode and the source
operand is an immediate addressing mode, the prefix byte ptr or word ptr should be appended after
the SUB instruction to denote the data size of the immediate operand.
c. Both source and destination operands should be of the same data size. For example, SUB CX, DL is
invalid.
d. All status flags are affected after execution.
Example:
MOV AX, 3333
MOV BX, 2222
SUB AX, BX
Q: What will be the value of the different status flags after execution?
A: CF = 0, OF = 0, PF = 1, ZF = 0, AF = 0, SF = 0
5.10.2 SBB
The SBB instruction subtracts the source operand and the carry flag from the destination operand.
Figure 5.12 illustrates the definition of the SBB instruction, while Figure 5.11 illustrates the allowed operands for the
SBB instruction.
Figure 5.12
SBB instruction
There are some important facts to remember about the SBB instruction. These are as follows:
a. In the SBB instruction, the current value of the carry flag (i.e., subtract 1 if carry flag is set and subtract
0 if carry flag is reset) is subtracted together with the source and destination operand.
b. The SBB instruction can be used to write routines to subtract numbers longer than 16 bits.
c. All important facts mentioned in the SUB instruction also apply to the SBB instruction.
Example:
MOV AX, 0002
SUB AX, 0001
SBB AX, 0000
The initial value of register AX is 0002. After executing the 2nd instruction, register AX contains a value of 0001
and the CF is 0. After the 3rd instruction, register AX contains a value of 0001 (destination operand is 0001, source
operand is 0000, and carry flag is 0).
5.10.3 DEC
DEC instruction subtracts 1 from the destination operand. Figure 5.13 illustrates the definition of DEC
instruction, while Figure 5.14 illustrates the allowed operands for the DEC instruction.
Figure 5.13
DEC instruction
Figure 5.14
Allowed operands for DEC instruction
There are some important facts to remember about the DEC instruction. These are as follows:
Example:
MOV AX, 0055
DEC AH
Q: What will be the value of the different status flags after execution?
A: ZF = 0, AF = 1, SF = 1, OF = 0, PF = 1, carry flag remains unchanged
In this example, register AL is not affected since only register AH is decremented. AL still retains the value of
55, while AH now has a value of FF (00-1).
5.10.4 NEG
The NEG instruction converts the specified operand to its 2’s complement equivalent and the result is
returned to the operand location. This is, in effect, reversing the sign of an integer. Figure 5.15 illustrates the definition
of NEG instruction, while Figure 5.16 illustrates the allowed operands for the NEG instruction.
Figure 5.15
NEG instruction
Destination Example
Register NEG AX
Memory NEG byte ptr BETA
Figure 5.15
Allowed operands for NEG instruction
a. Attempting to negate an operand having a value of zero causes no change to the operand and resets
the carry flag (i.e., CF = 0), else the carry flag is set (i.e., CF = 1).
b. Attempting to negate an operand having a value of either 80h (-128 decimal) or 8000h (-32768)
causes no change to the operand and sets the overflow flag (i.e., OF = 1), else the overflow is reset
(i.e., OF = 0).
c. If the destination operand is a memory addressing mode, the prefix byte ptr or word ptr should be
appended after the NEG instruction to denote the data size of the destination operand.
Example:
MOV AL, 00
NEG AL
Q: What will be the value of the carry flag and overflow flag after execution?
A: OF = 0, CF = 0
In this example, the operand is zero. Therefore, the operand is not changed (i.e., register AL still has a
value of 0) and the carry flag is reset. The operand is either 80h or 8000h, so the overflow flag value is 0.
Example:
MOV BL, 09
NEG BL
Q: What will be the value of the carry flag and overflow flag after execution?
A: OF = 0, CF = 1
In this example, the 2’s complement of 09 is F7 (or -9 in decimal). The operand is either 0 nor 80h nor 8000h,
therefore, the carry flag is set and the overflow flag is reset.
Example:
MOV SI, 8000
NEG SI
Q: What will be the value of the carry flag and overflow flag after execution?
A: OF = 1, CF = 1
In this example, the operand is 8000, thus, the operand is not changed (i.e., register SI still has a value of
8000) and the overflow flag is set. Since the operand is not zero, the carry flag value is set.
The DAS instruction adjust the result of a previous subtraction of two valid packed decimal operands. Figure
5.17 illustrates the definition of DAS instruction.
Figure 5.17
DAS instruction
There are some important facts to remember about the DAS instruction. These are as follows:
Example:
MOV AL, 34
MOV BL, 19
SUB AL, BL
DAS
In the example, the values of AL and BL are viewed as BCD (i.e., packed decimal). Since DAS instruction
will be used to adjust the subtraction operation, the destination operand should be in AL. Prior to the DAS instruction,
the value of AL is 1Bh. After the DAS instruction, the value of register AL is adjust to 15. The Operation is as follows:
Since the lower nibble of the intermediate result is greater than 9, DAS adjust the result by subtracting 6 to
the lower nibble.
The ASS instruction adjust the result of a previous subtraction of two valid unpacked decimal operands.
Figure 5.18 illustrates the definition of the AAS instruction.
Figure 5.18
AAS instruction
There are some important facts to remember about the AAS instruction. These are as follows:
Example:
MOV AL, 39 ; AL contains the ASCII value of 9
MOV BL, 34 ; BL contains the ASCII value of 4
SUB AL, BL
AAS
In this example, the values of register AL and BL are viewed as ASCII numbers (i.e., unpacked decimal).
Since the AAS instruction will be used to adjust the operation, the destination operand of the SUB instruction should
be in register AL. Prior to AAS, the value of AL is 05. After the AAS instruction, the value of register AL is adjusted to 05.
The operation is as follows:
Since the least significant nibble is not greater than 9, thus the only adjustment needed is to zero out the
most significant nibble.
5.11.1 MUL
The MUL instruction performs an unsigned multiplication of the source operand and the accumulator.
Figure 5.19 illustrates the definition of MUL instruction, while Figure 5.20 illustrates the allowed operands for the MUL
instruction.
Figure 5.19
MUL instruction
Destination Example
Register MUL AX
Memory MUL byte ptr BETA
Figure 5.20
Allowed operands for MUL and IMUL instructions
There are some important facts to remember about the MUL instruction. These are as follows:
a. If the source operand is a byte, it is multiplied by register AL and the result is returned to register AX.
b. If the source operand is a word, it is multiplied by register AX and the result is returned to register
DX (most significant word) and AX (least significant word).
c. In the MUL instruction, operands are viewed as unsigned integers.
d. If the upper half of the result (register AH for byte source, register DX for word source) is zero, CF
and OF are reset; otherwise, they are set.
e. AF, PF, SF, and ZF are undefined after execution.
Example:
MOV AX, 0002
MOV BX, 0005
MUL BL
Q: What will be the value of the carry flag and overflow flag after execution?
A: CF = 0, OF = 0
In the given example, the source operand of the MUL instruction is a byte. This means that it is
multiplied with AL. The operation is, therefore, AX 02 * 05. After execution, register AX will have a value of 000A.
Since the upper half of the result is zero, both carry flag and overflow flag are reset.
The IMUL instruction performs a signed multiplication of the source operand and the accumulator.
Figure 5.21 illustrates the definition of IMUL instruction, while Figure 5.20 illustrates the allowed operands for the IMUL
instruction.
Figure 5.21
IMUL instruction
There are some important facts to remember about the IMUL instruction. These are as follows:
a. If the source operand is a byte, it is multiplied by register AL and the result is returned to AX
b. If the source operand is a word, it is multiplied by register AX and the result is returned to register
DX (most significant word) and AX (least significant word).
c. In the IMUL instruction, operands are viewed as signed integers.
d. If the upper half of the result (AH for byte source, DX for word source) is the sign extension of the
lower half of the result, CF and OF are reset; otherwise, they are set.
e. AF, PF, SF, and ZF are undefined after execution.
Example:
MOV AX, 00FE
MOV BX, 00FE
IMUL BL
Q: What will be the value of the carry flag and overflow flag after execution?
A: CF = 0, OF = 0
In the example, since the source operand of the IMUL instruction is a byte, it is automatically multiplied
with AL. The operation is, therefore, AX (-2) * (-2), (i.e., in the IMUL instruction, operands are viewed as signed
integers). After execution, register AX will have a value of 0004. Since the upper half of the result is the signed extension
of the lower half of the result, both carry flag and overflow flag are reset.
5.11.3 AAM
The AAM instruction adjust the result of a previous multiplication of two valid unpacked decimal
operands. Figure 5.22 illustrates the definition of AAM instruction.
Figure 5.22
AAM instruction
a. The most significant nibble of an operand should be zero. This can be compared with addition and
subtraction in which operands are viewed as ASCII (i.e., most significant nibble is a 3).
b. The result of the previous operation should be in register AX.
c. The instruction will adjust the result as follows: the value of register AL is divided with 0Ah and the
quotient is placed in AH, while the remainder is placed in AL.
d. OF, CF, and AF are undefined after execution.
e. AAM should be executed immediately after MUL or IMUL instruction.
Example:
MOV AL, 05
MOV BL, 03
MUL BL
AAM
After execution the MUL instruction, AX has a value of 000F. (Equivalent to decimal 15). After the AAM
instruction, thus, AH now contains 01h (i.e., 000F / 0Ah) while AL now contains 05h (i.e., 000F mod 0Ah). AX now
contains the adjusted unpacked decimal value of the previous result (i.e., 0105 is the unpacked BCD equivalent of 15)
The CBW instruction sign extends the byte data in register AL to register AH. Figure 5.23 illustrates the
definition of CBW instruction.
Figure 5.23
CBW instruction
There are some important facts to remember about the CBW instruction. These are as follows:
Example:
MOV AX, 1234
CBW
Example:
MOV AX, 8088
CBW
The sign bit (most significant bit) of register AL is 1. The sign extension is, therefore, FF and is stored in
register AH.
5.12.2 CWD
The CWD instruction sign extends the word data in register AX to register DX. Figure 5.24 illustrates the
definition of CWD instruction.
Figure 5.24
CWD instruction
There are some important facts to remember about the CWD instruction. These are as follows:
Example:
MOV AX, 1234
CWD
The sign bit (most significant bit) to register AX is 0. The sign extension is , therefore, 0000 and is stored
in register DX.
Example:
MOV AX, 8088
CWD
5.12.3 DIV
The DIV instruction performs an unsigned division of the accumulator by the source operand. Figure
5.25 illustrates the definition of DIV instruction, while Figure 5.26 illustrates the allowed operands for the DIV
instruction.
Figure 5.25
DIV instruction
Destination Example
Register DIV AX
Memory DIV byte ptr BETA
Figure 5.26
Allowed operands for DIV and IDIV instructions
There are some important facts to remember about the DIV instruction. These are as follows:
a. If the source operand is a byte, register AX is divided by this byte-sized source operand, with the
results returned in register AL and the remainder in register AH.
b. If the source operand is a word, register pair DX, AX is divided by this word-sized source operand,
with the results returned in register AX and the remainder in register DX.
c. In the DIV instruction, operands are viewed as unsigned integers.
d. If the quotient exceeds the capacity of the destination register (i.e., FFh for byte source, FFFFh for
word source), the quotient and remainder are undefined, and an INT 0 is generated.
e. Non-integral quotients are truncated.
f. All status flags are undefined after execution.
Example:
MOV AX, 0005
MOV BX, 0002
DIV BL
In the example above, the source operand of the DIV instruction is a byte. This means that register AX
is divided by register BL. The operation is, therefore, AL – 05 div 02 and AH – 05 mod 02.
The IDIV instruction performs a signed division of the accumulator by the source operand. Figure 5.27
illustrates the definition of IDIV instruction, while Figure 5.26 illustrates the allowed operands for the IDIV instruction.
Figure 5.27
IDIV instruction
There are some important facts to remember about the IDIV instruction. These are as follows:
a. If the source operand is a byte, register AX is divided by this byte-sized source operand, with the
results returned in register AL and the remainder in register AH.
b. If the source operand is a word, register pair DX, AX is divided by this word-sized source operand,
with the results returned in register AX and the remainder in register DX.
c. In the IDIV instruction, operands are viewed as signed integers
d. If the source operand is a byte, the maximum positive quotient is 7Fh, and the minimum negative
quotient is 81h.
e. If the source operand is a word, the maximum positive quotient is 7FFFh, and the minimum negative
quotient is 8001h.
f. If the quotient exceeds the maximum (positive) or the minimum (negative), the quotient and
remainder are undefined, and an INT 0 is generated.
g. Non-integral quotients are truncated.
h. The remainder has the same sign as the dividend
i. All status flags are undefined after execution.
Example:
MOV AX, FFFE
MOV DX, FFFF
MOV BX, FFFE
IDIV BX
In the example, the source operand of the IDIV instruction is a word. This means that register DX, AX is
divided by register BL. The operation is, therefore, AX (-2) div (-2) and DX (-2) mod (-2).
5.12.5 AAD
The AAD instruction modifies the numerator in register AL before dividing two valid unpacked decimal
operands. Figure 5.28 illustrates the definition of AAD instruction.
Figure 5.28
AAD instruction
There are some important facts to remember about AAD instruction. These are as follows:
a. AAD instruction should be executed before issuing the DIV instruction when dividing two valid
unpacked decimal operands.
b. The instruction will adjust the operand (i.e., register AL) as follows: the value of register AH is
multiplied with 0Ah and added with the value of the register AL. The result is placed in register AL.
AH is zeroed out after adjustment.
c. AF, CF, OF are undefined after execution.
d. AAD instruction works hand in hand with DIV instruction only.
Example:
MOV AX, 0105
AAD
MOV BL, 02
DIV BL
In the example, after execution the AAD instruction, register AX now has a value of 000Fh. This value
is then divided by BL.