L5 Arithmetic Logic and Shift Instr
L5 Arithmetic Logic and Shift Instr
The purpose of this worksheet is to present the arithmetical, logic, rotation and
shift instructions for the microprocessor 80x86.
Theoretical approach
The 16 bits microprocessors from the 80x86 family have computing instructions
to allow operations on 8 or 16 bits and to implement routines for multibytes or multiword
operations. By computing we mean:
- arithmetical operations: add, subtract, multiply, divide, increment, decrement,
complemental for 2,compare;
- logic operations: and, or, xor, complemental for 1;
- rotation and shift operations.
Arithmetical instructions:
Arithmetical operations are using numbers in bytes or word format, with or
without sign representation in complemental for 2. Add and subtract operations can also
use operants of type BCD unpacked (one decimal digit by byte) or packed BCD (two
decimal digits by byte). Multiply and divide operations can be used for unpacked BCD.
In the following grid <s> and <d> represent the „source” operant and „destination”
operant. Arithmetical instructions generally affect the following conditioning indicators:
AF, CF, OF, DF, PF, ZF. These indicators are written according to the result of the
instruction.
1
CMP <d>, <s> The indicators maintain the SUB AF,CF,OF,PF,SF,ZF
positioning but the destination {<d>}
doesn’t change
2
For adding and incrementing are used the instructions ADD, ADC and INC
according to syntax:
For subtract and decrement operations are used SUB, SBB, DEC and NEG
according to syntax:
Example:
DATA SEGMENT
MEM8 DB 39
DATA ENDS
CODE SEGMENT
... ... with sign unsigned
MOV AL, 26 ;load al 26 26
INC AL ;increment al 1 1
ADD AL, 76 ;add immediate date 76 76
; ---- ----
; 103 103
ADD AL, MEM8;add memory 39 39
; ---- ----
; 142 -114+OF
MOV AH, AL ;copy to ah 142
ADD AL, AH ;add register 142
; ----
; 28+CF
... ...
CODE ENDS
3
For this example the add operation was on 8 bits. When the sum is over 127 the OF is
written, when over 255 the CF is written.
Example:
DATA SEGMENT
MEM8 DB 122
DATA ENDS
CODE SEGMENT
……
MOV AL, 95 ;load al 95 95
DEC AL ;decrement -1 -1
SUB AL, 23 ;subtract immediate value -23 -23
---- ----
71 71
SUB AL, MEM8 ;subtract memory -122 -122
---- ----
205+CF -51
MOV AH, 119;load ah
SUB AL,AH ;subtract register -119
----
86+OF
……
CODE ENDS
The instructions ADC and SBB allow implementation for multi-byte or multi-
word operations. They perform the action of ADD and SUB and also add or subtract the
value of CF indicator.
Example:
DATA SEGMENT
MEM32 DD 316423
DATA ENDS
CODE SEGMENT
……
MOV AX, 43981
SUB DX, DX ;load dx, ax 43981
ADD AX, WORD PTR MEM32[0] ;add inf. word
ADC DX, WORD PTR MEM32[2] ;add sup. word 316423
; --------
;result in dx,ax 360404
……
CODE ENDS
4
Example:
DATA SEGMENT
MEM32A DD 316423
MEM32B DD 156739
DATA ENDS
CODE SEGMENT
……
MOV AX, WORD PTR MEM32A[0] ;load inf. word
MOV DX, WORD PTR MEM32A[2] ; load sup. word
SUB AX, WORD PTR MEM32B[0] ;subtract inf. word
SUB AX, WORD PTR MEM32B[2] ; subtract sup. word
……
CODE ENDS
MUL is used for multiplying unsigned numbers. IMUL is used for multiplying
numbers wtih sign representation. The syntaxes are :
Example:
DATA SEGMENT
MEM16 DW –30000
DATA ENDS
CODE SEGMENT
;unsigned multiply on 8 bits
MOV AL, 23 ;load al 23
MOV BL, 24 ;load bl 24
MUL BL ;multiply bl
; ----
;result in ax 552
;positioning for CF and OF
5
;multiply with sign on 16 bits
MOV AX, 50 ;load ax 50
IMUL MEM16 ;multiply with mem. -30000
; --------
;result in dx,ax -1500000
; positioning for CF and OF
……
CODE ENDS
DIV instruction is used for dividing unsigned numbers; IDIV is used for
numbers without sign representation. The syntaxes are:
In order to divide a 16 bits number by an 8 bits number the first operant is loaded
in AX. This register looses it’s information after the operation ends. The first operant is
specified as an 8 bits operant of register type or memory location. At the end AL stores
the quotient and AH the rest.
In order to divide a 32 bits number by a 16 bits number the first operant is loaded
in the pair DX, AX. The information stored in DX and AX will be lost after the
operation. The first operant is specified as a 16 bits operant of register type or memory
location. At the end AX stores the quotient and DX the rest.
For dividing 2 numbers of equal length (8 or 16 bits) the first action is to convert
to a double length (16 or 32 bits) the first operant. For unsigned numbers the conversion
consists in deleting the upper byte of the first operant, register AH, and respectively the
most significant byte, register DX. For sign represented numbers conversion consists in
sign extension and is obtained through CWB and CWD instructions.
If the divider is 0 or the quotient exceeds it’s assigned register (AL or AX) then
the processor generates a level 0 interruption. If this interruption is not handled by the
developer the operating system will abandon the program. There are two methods for
dealing with the situation: testing the divider before the operation takes place and calling,
when needed, a routine for handling errors; writing your own routine for handling errors
to replace the routine for level 0 interruption.
Example:
DATA SEGMENT
MEM16 DW –2000
MEM32 DD 500000
DATA ENDS
6
CODE SEGMENT
; unsigned dividing of a 16 bits operant
;by an 8 bits operant
MOV AX, 700 ;load operant 700
MOV BL, 36 ;load divider 36
DIV BL ;unsigned dividing
;quotient is in al 19
;rest is in ah 16
;sign dividing of a 32 bits operant
;by a 16 bits operant
MOV AX, WORD PTR MEM32[0] ;load ax
MOV DX, WORD PTR MEM32[2] ; load dx 500000
IDIV MEM16 ; sign dividing
; quotient is in ax -250
; rest is in dx 0
; sign dividing of a 16 bits operant
;by a 16 bits operant
The instruction set has 4 instructions for decimal correction: AAA (decimal
correction after adding), AAS (decimal correction after subtracting), AAM (decimal
correction after multiplying) and AAD (decimal correction before dividing), which allow
arithmetical operations for BCD unpacked. For this purpose classic arithmetical
instructions are used, followed (preceded) by an instruction to correct the result.
Arithmetical operations must apply on bytes so the result can be found in AL, which is
used by correction instructions. If an operation implies 2 one digit operands with a result
of two digits, the instruction for correction will place the least significant digit in AL, and
the most significant in AH, deleting the content of this register. If the digit stored in AL
generates carry to AH or needs to borrow from AH the indicators CF and AF are
positioned.
Example:
;Adding in BCD unpacked
MOV AX, 9 ;load ax 0009h
MOV BX,3 ; load bx 0003h
ADD AL, BL ;adding 000ch
AAA ;decimal correction for add ax=0102h
7
; AF and CF are positioned
;Subtract in BCD unpacked
MOV AX, 0103H ;load ax 0103h
MOV BX, 4 ; load bx 0004h
SUB AL, BL ;subtract 01feh
AAS ; decimal correction for
;subtraction ax=0009h
;AF and CF are positioned
;Multiply in BCD unpacked
MOV AX, 0903H ; load ax 0903h
MUL AH ;unsigned multiply 001bh
AAM ; decimal correction after MUL ax=0207h
;Dividing in BCD unpacked
MOV AX, 0209H ; load în ax 0209h
MOV BL, 2 ; load bl 02h
AAD ; decimal correction before
;dividing AX=0019h
DIV BL ;unsigned dividing 010ch
;quotient in al 0ch
;rest in ah 01h
AAM ;decimal correction after
;dividing the quotient ax=0102h
;the rest is lost
The rest will be lost. If needed, it must be saved in a different register before
correcting the quotient. The rest can also be corrected.For this it must be transfered in
AL.
Example:
;Adding in packed BCD
MOV AX, 8833H ;load ax 8833h
ADD AL, AH ;add to al al=0bbh
DAA ;decimal correction
;after adding al=021h
; CF is set
;the result is 121h
8
;Subtracting in packed BCD
MOV AX, 3883H ;load ax 3883h
SUB AL, AH ;subtract al=04bh
DAS ;decimal correction
;after subtracting al=045h
; CF is 0
Logic instructions:
Logic instructions operate on bits, over bits of same rank of two operants.There
are 5 logic instructions: AND, TEST, OR, XOR and NOT.
The syntax:
AND {register | memory}, { register | memory | immediate date}
TEST { register | memory }, { register | memory | immediate date }
OR { register | memory }, { register | memory | immediate date }
XOR { register | memory }, { register | memory | immediate date }
NOT { register | memory }
Example:
;example for AND
MOV AL, 35H ;load al 00110101
AND AL, 0FBH ;and with immediate date 11111011
; ------------
; 00110001
AND AL, 0F8H ; 11111000
; ------------
; 00110000
9
;example for OR
MOV AL, 35H ;load al 00110101
OR AL, 08H ;or with immediate date 00001000
; ------------
OR AL, 07H ; or with immediate date 00000111
; ------------
; 00111111
;example for XOR
MOV AL, 35H ;load al 00110101
XOR AL, 08H ;xor with immediate date 00001000
; ------------
; 00111101
XOR AL, 07H ; xor with immediate date 00000111
; ------------
; 00111010
Logic instructions can be used to compare an operant with 0(or BX, BX instead of
CMP BX, 00) or to delete an operant (XOR CX, CX; SUB CX, CX în loc de MOV CX,
00) having a more compact form.
10
ROL <s>, 1 Rotate left by carry. If CF <> sign CF, OF
then OF becomes 1
ROL <s>, CL Rotate left by carry with a number of CF, OF
positions indicated by CL.
ROR <s>,1 Rotate right by carry. If (CF) <> sign CF, OF
OF becomes 1.
ROR <s>, CL Rotate right by carry with a number CF, OF
of positions indicated by CL.
RCL <s>, 1 Rotate left with carry. If (CF) <> sign CF, OF
OF becomes 1.
RCL <s>, CL Rotate left with carry with a number CF, OF
of positions indicated by CL.
RCR <s>, 1 Rotate right with carry. If (CF) <> CF, OF
sign OF becomes 1.
RCR <s>, CL Rotate right with carry with a number CF, OF
of positions indicated by CL.
Destination operant must contain the address that will be shifted (register or
memory location).After the instruction is executed here will be stored the shifted/rotated
value. Source operant must contain the number of bits over witch the shift/rotation takes
place. It can be the immediate value 1 or register CL
The following figures show the result of these instructions on a byte operant for one
position shifting/rotation.
SHL, SAL
Carry 7 6 5 4 3 2 1 0
0
SHR
Carry 7 6 5 4 3 2 1 0
11
SAR
Carry 7 6 5 4 3 2 1 0
s ROL
Carry 7 6 5 4 3 2 1 0
ROR
Carry 7 6 5 4 3 2 1 0
RCL
Carry 7 6 5 4 3 2 1 0
RCR
Carry 7 6 5 4 3 2 1 0
Example:
;a number stored in ax
;is multiplied by 10
SHL AX, 1 ;*2
MOV BX, AX ;
SHL AX, 1 ;*4
SHL AX, 1 ;*8
ADD AX, BX ;*10
12
;a number stored in ax represented in C2 with sign
;is divided by 2
MOV AX, -16 ;
SAR AX, 1 ;/2
DATA SEGMENT
MEM32 DD 500000
DATA ENDS
CODE SEGMENT
……
SHR WORD PTR MEM32[2], 1 ;shifting in CF
RCR WORD PTR MEM32[0], 1 ;rotation with CF
……
CODE ENDS
Laboratory tasks
1. Study the examples.
2. Follow the examples with Turbo Debugger.
3. Write a program that generates an integer in byte representation and stores it
to a REZ location after the formula:
REZ = AL*NUM1+(NUM2*AL+BL)
All parameters are byte represented.
4. Implement the following operations using arithmetic and shift instructions:
AX = 7*AX–2*BX–BX/8
Parameters are byte represented.
5. Design an algorithm to multiply and divide two unsigned/signed numbers
represented in C2 on 1 and on 2 bytes.
6. (complementary) Design an algorithm to multiply two 4 bytes numbers in C2
representation.
13