Chapter 7 - Integer Arithmetic

shift operation - this operation involves the bit to bit movement of the contents of memory or a register. The general form of a shift operation is as follows:

[<label>] <opcode> <destination>,<shift-count> where opcode is one of the following instructions:

(1) SAR (2) SHR (3) ROR (4) RCR (5) SAL (6) SHL (7) ROL (8) RCL 9) SHLD 10) SHRD

and destination specifies a register or memory location. shift-count is either an immediate 8 value or the value specified in the cl-register.

Note: Using the cl-register does not alter the value in the cl after the instruction is executed.

There are three basic types of shift operations:

(1) Arithmetic
(2) Logical
(3) Rotate

In general, we are looking at the following acceptable operands for these shift operations:

shift-instruction destination,count

where destination,count can be 
  reg,imm8
  mem,imm8
  reg,cl
  mem,cl

Arithmetic Shifts

Arithmetic shifts treat the operand as a two's complement number.

(i50) SAR - Arithmetic right-shift (p. 231)

Note: with SAR, the sign bit never changes; therefore, OF always equals 0

SAR -> floor(x/(2^n))

(i51) SAL - Arithmetic left-shift

SAL -> x*(2^n)

Note1: If the sign bit changes on the last bit shifted, then the OF bit in the flags register is set; otherwise, OF is cleared.

Q#1: Does the OF represent the result of the shift accurately in all cases? Why or why not?

Logical Shifts

Logical shifts treat the operand as an unsigned integer.

(i52) SHR - Logical right-shift (p. 230)

SHR -> floor(x/(2^n))

(i53) SHL - Logical left-shift (p. 229)

Note: This instruction behaves exactly like the SAL. Assembler produces the same machine language code.

Rotate

rotate - treats the operand as if it were a circular collection of bits.

Two types of rotate exist:
(1) Straight rotate
(2) Rotate through the carry

straight rotate - operation treats the carry separately from the operand.

(i54) ROR - right rotate (p. 232)

(i55) ROL - left rotate (p. 231)

rotate-through carry - this operation treats the carry as a 1-bit extension.

(i56) RCR - right rotate-through carry (p. 233)

(i57 RCL - left rotate-through carry (p. 232)

P#1: The parity of a number is identified by the number of 1-bits. An even number of 1's implies even parity and an odd number of 1's implies odd parity. Write a procedure parity that prints EVEN or ODD depending on whether the value passed to the function through the AX-register is even parity or odd parity.

(i58) SHLD - shift-left double (p. 234)

(i59) SHRD - shift-right double (p. 234)

Flags Register

bit  15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
                 OF DF IF TF SF ZF    AF    PF    CF

Multiplication

The x86 microprocessor supplies two different kinds of multiplies and two different kinds of divides. We've already covered divide.

In general,

Multiplicand   Multiplier   Product
AL             r/m8         AX
AX             r/m16        DA:AX
EAX            r/m32        EDX:EAX
Unsigned integer multiply is MUL and signed two's complement integer multiply is IMUL. The general form is:

(i60) [<label>] MUL <source>

(i61) [<label>] IMUL <source>

MUL Instruction:
The MUL instruction affects the following flags: SF, ZF, AF, PF, OF, and CF. In particular:

(1) The SF, ZF, AF, and PF flags are undefined after executing this instruction.
(2) If the upper half of the product is nonzero (ah for byte operation and dx for word), both the OF and CF flags are set; otherwise, they are clear.

IMUL Instruction:
The IMUL instruction affects the following flags: SF, ZF, AF, PF, OF, and CF. In particular:

(1) The SF, ZF, AF, and PF flags are undefined after executing this instruction.
(2) If the upper half of the product is the sign extension of the lower half, then the OF and CF bits are clear; otherwise they are set. Remember, for an 8-bit multiply, the upper half is the ah and for a 16-bit multiply, the upper half is the dx register.

Consider multiplying the following two values:

al and bl regs     mul bl                  
10000000           ah        al       of  cf
11111110           01111111  00000000  1   1

                   imul bl
                   ah        al       of  cf
                   00000001  00000000  1   1

Let's go over this example.

Note: The source operand can be either General Reg or MEM either of which can be a byte or word.


©Douglas J. Ryan / ryandj@pacificu.edu