Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
11 views

LectureNotes 12

assembly bit manipulation

Uploaded by

amirentezari.ac
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views

LectureNotes 12

assembly bit manipulation

Uploaded by

amirentezari.ac
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

Lesson No.

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.

1.1. BITWISE LOGICAL OPERATIONS


The 8088 processor provides us with a few logical operations that operate at the bit
level. The logical operations are the same as discussed in computer logic design;
however our perspective will be a little different. The four basic operations are AND, OR,
XOR, and NOT.
The important thing about these operations is that they are bitwise. This means that
if “and ax, bx” instruction is given, then the operation of AND is applied on
corresponding bits of AX and BX. There are 16 AND operations as a result; one for every
bit of AX. Bit 0 of AX will be set if both its original value and Bit 0 of BX are set, bit 1
will be set if both its original value and Bit 1 of BX are set, and so on for the remaining
bits. These operations are conducted in parallel on the sixteen bits. Similarly the
operations of other logical operations are bitwise as well.

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

Selective Bit Clearing


Another use of AND is to make selective bits zero in its destination operand. The
source operand is loaded with a mask containing one at positions which are retain their
old value and zero at positions which are to be zeroed. The effect of applying this
operation on the destination with mask in the source is to clear the desired bits. This
operation is called masking. For example if the lower nibble is to be cleared then the
operation can be applied with F0 in the source. The upper nibble will retain its old value
and the lower nibble will be cleared.

Selective Bit Setting


The operation can be used as a masking operation to set selective bits. The bits in the
mask are cleared at positions which are to retain their values, and are set at positions
which are to be set. For example to set the lower nibble of the destination operand, the
operation should be applied with a mask of 0F in the source. The upper nibble will
retain its value and the lower nibble will be set as a result.

Selective Bit Inversion


XOR can also be used as a masking operation to invert selective bits. The bits in the
mask are cleared at positions, which are to retain their values, and are set at positions,
which are to be inverted. For example to invert the lower nibble of the destination
operand, the operand should be applied with a mask of 0F in the source. The upper
nibble will retain its value and the lower nibble will be set as a result. Compare this
with NOT which inverts everything. XOR on the other hand allows inverting selective
bits.

Selective Bit Testing


AND can be used to check whether particular bits of a number are set or not.
Previously we used shifting and JC to test bits one by one. Now we introduce another
way to test bits, which is more powerful in the sense that any bit can be tested anytime
and not necessarily in order. AND can be applied on a destination with a 1-bit in the
desired position and a source, which is to be checked. If the destination is zero as a
result, which can be checked with a JZ instruction, the bit at the desired position in the
source was clear.
However the AND operation destroys the destination mask, which might be needed
later as well. Therefore Intel provided us with another instruction analogous to CMP,
which is non-destructive subtraction. This is the TEST instruction and is a non-
destructive AND operation. It doesn’t change the destination and only sets the flags
according to the AND operation. By checking the flags, we can see if the desired bit was
set or cleared.
We change our multiplication algorithm to use selective bit testing instead of
checking bits one by one using the shifting 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

You might also like