LectureNotes 12
LectureNotes 12
12
Extended Multiplication
We use extended shifting and extended addition to formulate our algorithm to do
extended multiplication. The multiplier is still stored in 16bits since we only need to
check its bits one by one. The multiplicand however cannot be stored in 16bits
otherwise on left shifting its significant bits might get lost. Therefore it has to be stored
in 32bits and the shifting and addition used to accumulate the result must be 32bits as
well.
Example 4.2
01 ; 16bit multiplication
02 [org 0x0100]
03 jmp start
04
05 multiplicand: dd 1300 ; 16bit multiplicand 32bit space
06 multiplier: dw 500 ; 16bit multiplier
07 result: dd 0 ; 32bit result
08
09 start: mov cl, 16 ; initialize bit count to 16
10 mov dx, [multiplier] ; load multiplier in dx
11
12 checkbit: shr dx, 1 ; move right most bit in carry
13 jnc skip ; skip addition if bit is zero
14
15 mov ax, [multiplicand]
16 add [result], ax ; add less significant word
17 mov ax, [multiplicand+2]
18 adc [result+2], ax ; add more significant word
19
20 skip: shl word [multiplicand], 1
21 rcl word [multiplicand+2], 1 ; shift multiplicand left
22 dec cl ; decrement bit count
23 jnz checkbit ; repeat if bits left
24
25 mov ax, 0x4c00 ; terminate program
26 int 0x21
05-07 The multiplicand and the multiplier are stored in 32bit space while
the multiplier is stored as a word.
10 The multiplier is loaded in DX where it will be shifted bit by bit. It
15-18 can be directly shifted in memory as well.
The multiplicand is added to the result using extended 32bit
20-21 addition.
The multiplicand is shifted left as a 32bit number using extended
shifting operation.
The multiplicand will occupy the space from 0103-0106, the multiplier will occupy
space from 0107-0108 and the result will occupy the space from 0109-010C. Inside the
debugger observe the changes in these memory locations during the course of the
algorithm. The extended shifting and addition operations provide the same effect as
would be provided if there were 32bit addition and shifting operations available in the
instruction set.
At the end of the algorithm the result memory locations contain the value 0009EB10
which is 65000 in decimal; the desired answer. Also observe that the number 00000514
which is 1300 in decimal, our multiplicand, has become 05140000 after being left
shifted 16 times. Our extended shifting has given the same result as if a 32bit number
is left shifted 16 times as a unit.
There are many other important applications of the shifting and rotation operations
in addition to this example of the multiplication algorithm. More examples will come in
coming chapters.
AND operation
AND performs the logical bitwise and of the two X Y X and Y
operands (byte or word) and returns the result to the 0 0 0
destination operand. A bit in the result is set if both 0 1 0
corresponding bits of the original operands are set; 1 0 0
otherwise the bit is cleared as shown in the truth 1 1 1
table. Examples are “and ax, bx” and “and byte [mem],
5.” All possibilities that are legal for addition are also legal for the AND operation. The
different thing is the bitwise behavior of this operation.
OR operation
OR performs the logical bitwise “inclusive or” of the
X Y X or Y
two operands (byte or word) and returns the result to
0 0 0
the destination operand. A bit in the result is set if
0 1 1
either or both corresponding bits in the original
operands are set otherwise the result bit is cleared as 1 0 1
shown in the truth table. Examples are “or ax, bx” and 1 1 1
“or byte [mem], 5.”
XOR operation
XOR (Exclusive Or) performs the logical bitwise X Y X xor Y
“exclusive or” of the two operands and returns the
0 0 0
result to the destination operand. A bit in the result is
0 1 1
set if the corresponding bits of the original operands
1 0 1
contain opposite values (one is set, the other is
1 1 0
cleared) otherwise the result bit is cleared as shown in
the truth table. XOR is a very important operation due to the property that it is a
reversible operation. It is used in many cryptography algorithms, image processing, and
in drawing operations. Examples are “xor ax, bx” and “xor byte [mem], 5.”
NOT operation
NOT inverts the bits (forms the one’s complement) of the byte or word operand.
Unlike the other logical operations, this is a single operand instruction, and is not
purely a logical operation in the sense the others are, but it is still traditionally counted
in the same set. Examples are “not ax” and “not byte [mem], 5.”
1.2. MASKING OPERATIONS
Example 4.3
01 ; 16bit multiplication using test for bit testing
02 [org 0x0100]
03 jmp start
04
05 multiplicand: dd 1300 ; 16bit multiplicand 32bit space
06 multiplier: dw 500 ; 16bit multiplier
07 result: dd 0 ; 32bit result
08
09 start: mov cl, 16 ; initialize bit count to 16
10 mov bx, 1 ; initialize bit mask
11
12 checkbit: test bx, [multiplier] ; move right most bit in carry
13 jz skip ; skip addition if bit is zero
14
15 mov ax, [multiplicand]
16 add [result], ax ; add less significant word
17 mov ax, [multiplicand+2]
18 adc [result+2], ax ; add more significant word
19
20 skip: shl word [multiplicand], 1
21 rcl word [multiplicand+2], 1 ; shift multiplicand left
22 shl bx, 1 ; shift mask towards next bit
23 dec cl ; decrement bit count
24 jnz checkbit ; repeat if bits left
25
26 mov ax, 0x4c00 ; terminate program
27 int 0x21
12 The test instruction is used for bit testing. BX holds the mask and in
every next iteration it is shifting left, as our concerned bit is now the
next bit.
22-24
We can do without counting in this example. We can stop as soon as
our mask in BX becomes zero. These are the small tricks that
assembly allows us to do and optimize our code as a result.
Inside the debugger observe that both the memory location and the mask in BX do not
change as a result of TEST instruction. Also observe how our mask is shifting towards
the left so that the next TEST instruction tests the next bit. In the end we get the same
result of 0009EB10 as in the previous example.
EXERCISES
1. Write a program to swap every pair of bits in the AX register.
2. Give the value of the AX register and the carry flag after each of the following
instructions.
stc
mov ax, <your rollnumber>
adc ah, <first character of your name>
cmc
xor ah, al
mov cl, 4
shr al, cl
rcr ah, cl
3. Write a program to swap the nibbles in each byte of the AX register.
4. Calculate the number of one bits in BX and complement an equal number of least
significant bits in AX.
HINT: Use the XOR instruction
5. Write a program to multiply two 32bit numbers and store the answer in a 64bit
location.
6. Declare a 32byte buffer containing random data. Consider for this problem that
the bits in these 32 bytes are numbered from 0 to 255. Declare another byte that
contains the starting bit number. Write a program to copy the byte starting at this
starting bit number in the AX register. Be careful that the starting bit number
may not be a multiple of 8 and therefore the bits of the desired byte will be split
into two bytes.
7. AX contains a number between 0-15. Write code to complement the
corresponding bit in BX. For example if AX contains 6; complement the 6th bit of
BX.
8. AX contains a non-zero number. Count the number of ones in it and store the
result back in AX. Repeat the process on the result (AX) until AX contains one.
Calculate in BX the number of iterations it took to make AX one. For example BX
should contain 2 in the following case:
AX = 1100 0101 1010 0011 (input – 8 ones)
AX = 0000 0000 0000 1000 (after first iteration – 1 one)
AX = 0000 0000 0000 0001 (after second iteration – 1 one) STOP