3.4 Which bit of the 8086 FLAG register is used by the string instructions? How?
Illustrate this by using the 8086 MOVSB instruction.
The Directional Flag (D) is used in string instructions in the 8086 microprocessor. When the Directional
Flag is set (1), the string data is accessed from higher memory locations towards lower memory
locations. When the Directional Flag is reset to 0, the string data is accessed from lower memory
locations towards higher memory locations.
ORG 100h ; Origin address where the program will be loaded
MOV AX, 0 ; Load 0 into AX register
MOV DS, AX ; Initialize Data Segment (DS) with 0
; Initialize source and destination indices
MOV SI, 2000h ; Source index (address in DS segment)
MOV DI, 3000h ; Destination index (address in ES segment)
MOV CX, 10 ; Number of bytes to copy
CLD ; Clear Direction Flag (set forward direction)
MOVSB ; Copy byte from [DS:SI] to [ES:DI], increment SI and
DI
HLT ; Halt the program
RET
3.6 What is the purpose of the TF bit in the FLAG register?
The Trap Flag (TF) bit in the flag register is used for single-step control. When the TF bit is set to 1, a
program can be run in single-step mode. This allows the user to execute one instruction of a program at
a time for debugging.
The flag register is used to store the results of arithmetic and logic operations. The flags in the flag
register provide information about the outcome of these operations.
3.7 If [BL]=36 in base 16 (ASCII code for 6) and [CL]=33 base 16 (ASCII code for 3)
,write an 8086 assembly program which will add the contents of BL and CL and then
provide the result in decimal. store the result in CL
ORG 100h ; Origin address where the program will be loaded
MOV BL, 36 ; Load BL with ASCII code for '6'
MOV CL, 33 ; Load CL with ASCII code for '3'
SUB BL, '0' ; Convert ASCII code to actual digit value ('6' - '0'
= 6)
SUB CL, '0' ; Convert ASCII code to actual digit value ('3' - '0'
= 3)
ADD CL, BL ; Add the contents of BL to CL
ADD CL, '0' ; Convert the sum back to ASCII code
MOV AH, 2 ; AH = 2 for displaying a character
MOV DL, CL ; Load DL with the ASCII character to display
INT 21h ; Call DOS interrupt to display the character
HLT ; Halt the program
RET
3.8 What happens to the contents of the AX register after execution of the following
8086 instruction sequence;
MOV AX, 0F180H
CBW
CWD
After executing the given 8086 instruction sequence:
1. MOV AX, 0F180H : AX is loaded with the immediate hexadecimal value 0F180H .
2. CBW (Convert Byte to Word): Since the highest bit of AL (lower byte of AX) in 0F180H is 0
(positive number), AH (higher byte of AX) is filled with zeros. The contents of AX remain as
0F180H .
3. CWD (Convert Word to Doubleword): This instruction sign-extends the value in AX to DX:AX.
The highest bit of AX (0) is propagated to DX, filling DX with zeros. The contents of AX remain
as 0F180H , and the contents of DX become zero.
In summary, the contents of the AX register remain as 0F180H , and the contents of the DX register
become zero.
3.9 Determine the addressing modes for the following instruction
(a) MOV CH,8
(b) MOD AX,DS:START
(c) MOV [SI],AL
Certainly, let's analyze the addressing modes for each instruction:
(a) MOV CH, 8 :
This instruction uses immediate addressing mode.
The immediate value 8 is directly moved into the CH register.
(b) MOD AX, DS:START (assuming you meant MOV AX, [DS:START] ):
This instruction uses memory addressing mode.
[DS:START] denotes the memory location pointed to by the effective address calculated by
adding the value of the DS register and the displacement of START.
The content of this memory location is moved into the AX register.
(c) MOV [SI], AL :
This instruction uses indirect addressing mode.
[SI] represents the memory location pointed to by the value in the SI register.
The content of the AL register is moved into this memory location.
3.10 Consider MOV BX,DS:BEGIN. How many memory accesses are required by
the 8086 to execute the above instruction if BEGIN=0401H.
In the instruction MOV BX, DS:BEGIN , the 8086 needs to access memory twice in order to execute
the instruction. Here's why:
1. Memory Access 1: Fetching the Segment Value from DS:
The 8086 needs to access memory to fetch the segment value from the DS (Data Segment)
register. This segment value is used to calculate the effective address.
2. Memory Access 2: Fetching the Data from the Effective Address:
After obtaining the segment value from DS, the 8086 combines it with the displacement value
BEGIN to calculate the effective address. It then accesses memory again to fetch the data located
at that effective address and loads it into the BX register.
So, a total of 2 memory accesses are required to execute the instruction MOV BX, DS:BEGIN with
the given value BEGIN = 0401H .
3.12 Write and 8086 assembly program to add two 128-bit numbers stored in
memory in consecutive locations.
A simple 8086 assembly program to add two 128-bit numbers stored in consecutive memory locations-
ORG 100h ; Set the origin address to 100h
MOV SI, 0 ; Source index for accessing memory locations
MOV DI, 16 ; Destination index for storing the result
; Load the first 128-bit number into AX:BX:CX:DX
MOV AX, [SI] ; Load low-order word
MOV BX, [SI + 2] ; Load next word
MOV CX, [SI + 4] ; Load next word
MOV DX, [SI + 6] ; Load high-order word
; Add the second 128-bit number to the first number
ADD AX, [SI + 8] ; Add low-order word
ADC BX, [SI + 10] ; Add next word with carry
ADC CX, [SI + 12] ; Add next word with carry
ADC DX, [SI + 14] ; Add high-order word with carry
; Store the result back into memory
MOV [DI], AX ; Store low-order word
MOV [DI + 2], BX ; Store next word
MOV [DI + 4], CX ; Store next word
MOV [DI + 6], DX ; Store high-order word
INT 20h ; Terminate the program
RET
3.13 What are the reminder, quotient, and registers containing them after execution
of the following instruction sequence?
MOV DX, 0
MOV AX, -5
MOV BX, 2
IDIV BX
Here's the breakdown of the process:
MOV DX, 0: Clears the DX register, which will be used to hold the remainder of the division.
MOV AX, -5: Loads -5 into the AX register. AX holds the lower 16 bits of the dividend.
MOV BX, 2: Loads 2 into the BX register, which will be the divisor.
IDIV BX: Performs signed division of the DX:AX register pair by BX. After this operation, the quotient
will
be stored in AX, and the remainder will be stored in DX.
After the execution of the division instruction, the quotient and remainder will be as follows:
Quotient (AX): -2
Remainder (DX): 1
So, after the execution of the instruction sequence, the registers will contain:
DX: Remainder (1)
AX: Quotient (-2)
BX: Divisor (2)
3.14 Write an assembly language program to divide A5721624H by F271H. Store the
remainder and quotient onto the stack. Assume that the numbers are signed and
stored in the stack as follows:
SP
F271
A572 Increasing Address
1624
Assume that the stack segment and stack pointer are already initialized.
Here's an 8086 assembly language program that divides the signed number A5721624H by F271H,
stores
the remainder and quotient onto the stack, and follows your specified memory layout:
ORG 100h ; Set the origin address to 100h
MOV AX, 0A572h ; Load the high word of the dividend (A572H) into
AX
MOV DX, 1624h ; Load the low word of the dividend (1624H) into DX
MOV BX, 0F271h ; Load the divisor (F271H) into BX
CWD ; Sign-extend DX to match the sign of AX
IDIV BX ; Divide DX:AX by BX, result in AX (quotient) and DX
(remainder)
PUSH DX ; Push the remainder onto the stack
PUSH AX ; Push the quotient onto the stack
INT 20h ; Terminate the program
RET
Explanation:
1. The program starts at address 100h.
2. The dividend A5721624H is loaded into the AX register and then sign-extended into the DX:AX
register pair.
3. The divisor F271H is loaded into the BX register.
4. The IDIV instruction divides the DX:AX register pair by BX, storing the quotient in AX and the
remainder in DX.
5. The program pushes the remainder and quotient onto the stack using the PUSH instruction.
6. The HLT instruction halts the program.
7. The program ends with a return instruction (RET).
Make sure the stack segment (SS) and stack pointer (SP) are properly initialized before running this
program. The program divides A5721624H by F271H, and the results are stored on the stack.
3.15 Write an 8086 assembly language program to compute X = Y + Z - 12FFH
where X, Y, Z are 64-bit variables. The lower 32 bits of Y and Z are stored
respectively at offset 5000H and 5008H followed by the upper 32 bits. Store the lower
32 bits of the 64-bit result at offset 600H followed by the upper 32 bits.
Here's an 8086 assembly language program that computes the expression X = Y + Z - 12FFH for 64-bit
variables, following the memory layout you've specified:
ORG 100h ; Origin address where the program will be loaded
MOV SI, 5000h ; SI points to lower 32 bits of Y
MOV DI, 5008h ; DI points to lower 32 bits of Z
MOV AX, [SI] ; Load lower 32 bits of Y into AX
ADD AX, [DI] ; Add lower 32 bits of Z to AX
SBB DX, 0 ; Handle carry from AX addition
MOV SI, 5002h ; SI points to upper 32 bits of Y
MOV DI, 5010h ; DI points to upper 32 bits of Z
ADC AX, [SI] ; Add upper 32 bits of Y to AX
ADC DX, [DI] ; Add upper 32 bits of Z to DX (with carry)
SUB AX, 12FFh ; Subtract 12FFh from AX
SBB DX, 0 ; Subtract borrow (if any) from DX
MOV [600h], AX ; Store lower 32 bits of result at offset 600h
MOV [602h], DX ; Store upper 32 bits of result at offset 602h
HLT ; Halt the program
RET
In this program:
The source index SI is set to 5000h, where the lower 32 bits of Y are stored.
The destination index DI is set to 5008h, where the lower 32 bits of Z are stored.
The destination index BX is set to 6000h, where the lower 32 bits of the result will be stored.
The program loads the lower 32 bits of Y and Z into registers AX and CX, respectively.
It adds Y and Z and then subtracts 12FFH from the sum.
The result's lower 32 bits are stored at offset 6000H.
The program then loads the upper 32 bits of Y and Z into registers AX and CX, respectively.
It adds the upper 32 bits of Y and Z, propagating the carry from the lower 32-bit addition.
The upper 32 bits of the result are stored at offset 6004H.
3.16 Assume that register AL, BX and DX CX contain a signed byte, a signed word,
and a signed 32-bit number respectively. Write an 8086 assembly language program
that will compute the signed 32-bit result:
AL + BX − DXCX → DXCX
ORG 100h ; Origin address where the program will be loaded
MOV AH, 0 ; Clear AH register
MOVZX AX, AL ; Zero-extend AL to AX
CWDE ; Convert word to doubleword, sign-extending AX to
DX:AX
IMUL CX ; Multiply DX:AX by CX, result in DX:AX
ADD AX, BX ; Add BX to AX
ADC DX, 0 ; Add carry (if any) to DX
SUB DX, CX ; Subtract CX from DX
SBB AX, 0 ; Subtract borrow (if any) from AX
MOV DXCX, DX ; Store the result in DXCX
HLT ; Halt the program
RET
Explanation:
1. The program starts at address 100h.
2. The AL register is zero-extended to AX.
3. The CWDE instruction converts the word AX to a doubleword DX:AX, sign-extending AX.
4. The IMUL instruction multiplies DX:AX by CX, storing the result in DX:AX.
5. BX is added to AX, and the carry is added to DX.
6. CX is subtracted from DX, and the borrow is subtracted from AX.
7. The result is stored in DXCX.
8. The program halts with HLT.
3.17 Write an 8086 assembly language program to compute
X = 5 × Y + (Z/W ) Where offsets 5000H, 5002H respectively contain the 16-
bit signed integers Y, Z, and W. Store the 32-bit result in memory starting at offset
5006H. Discard the reminder of Z/W.
Here's an 8086 assembly language program to compute the expression X = 5 * Y + (Z / W) and store the
32-bit result in memory starting at offset 5006H:
ORG 100h ; Origin address where the program will be loaded
MOV SI, 5000h ; SI points to offset of Y
MOV DI, 5002h ; DI points to offset of Z
MOV AX, [SI] ; Load Y into AX
IMUL AX, 5 ; Multiply Y by 5
MOV BX, [DI] ; Load Z into BX
MOV CX, [5004h] ; Load W into CX (16-bit divisor)
IDIV CX ; Divide Z by W, quotient in AX
ADD AX, BX ; Add the result of (Z / W) to AX
MOV [5006h], AX ; Store the 32-bit result in memory at offset 5006h
HLT ; Halt the program
RET
Explanation:
1. The program starts at address 100h.
2. Y is loaded into AX and then multiplied by 5 using IMUL.
3. Z is loaded into BX and W is loaded into CX (as the divisor).
4. The IDIV instruction divides Z by W, storing the quotient in AX.
5. The result of (Z / W) is added to AX.
6. The 32-bit result is stored in memory at offset 5006h.
7. The program halts with HLT.
3.18 Write an 8086 instruction sequence to clear the trap flag to zero.
To clear the Trap Flag (TF) to zero in the 8086 processor, you can use the CLD (Clear Direction Flag)
instruction. The Direction Flag (DF) is bit 10 of the Flags register, and clearing the DF also clears the
TF. Here's the instruction sequence:
CLD ; Clear Direction Flag and Trap Flag
The CLD instruction clears both the Direction Flag (DF) and the Trap Flag (TF), setting them to zero.
3.19 Write an 8086 subroutine to compute
N 2
Xi
Y = ∑
N
i=1
where Xis are signed 8-bit integers and N = 100, The numbers are stored in consecutive locations.
Assume SI points to Xis and SP, DS, SS are already initialized.
Certainly! Here's an 8086 assembly subroutine to compute the sum of the expression you provided:
; Input: N = 100, Xis are stored in consecutive memory locations
starting from SI
; Output: Result Y in AX
ComputeSum:
MOV CX, 100 ; Load N = 100 into CX
MOV AX, 0 ; Clear AX to store the sum
SumLoop:
MOV AL, [SI] ; Load the current value Xi into AL
CBW ; Sign-extend AL to AX
IMUL AX, AX ; Square Xi (AX * AX)
ADD [SI], AL ; Store the squared value back in memory
(optional)
ADD AX, DX ; Add the squared value to the accumulator
INC SI ; Move to the next Xi
LOOP SumLoop ; Repeat for N times
MOV DX, 0 ; Clear DX for division
DIV CX ; Divide the accumulated sum by N (CX)
RET ; Return with the result Y in AX
Explanation:
1. The subroutine begins by loading the value of N (100) into the CX register and clearing AX to
store the sum.
2. Inside the loop, AL is loaded with the current value Xi, then sign-extended to AX using CBW.
3. The IMUL instruction is used to square the value of Xi (AX * AX).
4. The squared value is optionally stored back in memory at the same location (you can omit this
line if not needed).
5. The squared value is added to the accumulator (AX) to accumulate the sum.
6. SI is incremented to move to the next Xi value, and the loop (LOOP instruction) is repeated N
times.
7. After the loop, DX is cleared for the division, and the DIV instruction is used to divide the
accumulated sum by N.
8. The result Y is stored in AX, and the subroutine returns with RET.
3.20 Write an 8086 assembly program to move a block of data bytes of length 100 10
from the source block starting at location 2000H in ES = 1000H to the destination
block starting at location 3000H in the same extra segment.
Here's an 8086 assembly language program to move a block of data bytes of length 100 (in decimal)
from the source block starting at location 2000H in ES = 1000H to the destination block starting at
location 3000H in the same extra segment:
ORG 100h ; Origin address where the program will be loaded
MOV AX, 1000h ; Load segment address (ES = 1000H)
MOV DS, AX ; Set DS to the same segment as ES
MOV SI, 2000h ; Source index points to location 2000H
MOV DI, 3000h ; Destination index points to location 3000H
MOV CX, 100 ; Set the loop counter to move 100 bytes
CopyLoop:
MOV AL, [SI] ; Load a byte from the source
MOV [DI], AL ; Store the byte to the destination
INC SI ; Move to the next byte in the source
INC DI ; Move to the next byte in the destination
LOOP CopyLoop ; Repeat for the specified count
HLT ; Halt the program
RET
Explanation:
1. The program starts at address 100h.
2. The segment address 1000H is loaded into AX, and both DS and ES are set to this segment.
3. SI points to the source location at 2000H, and DI points to the destination location at 3000H.
4. The CX register is set to 100 to define the number of bytes to copy.
5. The loop copies each byte from the source to the destination using the MOV instruction.
6. The program halts with HLT.