• 沒有找到結果。

5-2 MULTIPLICATION AND DIVISION

在文檔中 THE INTEL MICROPROCESSORS (頁 185-191)

Only modern microprocessors contain multiplication and division instructions. Earlier 8-bit microprocessors could not multiply or divide without the use of a program that multiplied or divided by using a series of shifts and additions or subtractions. Because microprocessor manu-facturers were aware of this inadequacy, they incorporated multiplication and division instructions into the instruction sets of the newer microprocessors. The Pentium–Core2 processors contain special circuitry that performs a multiplication in as little as one clocking period, whereas it took over 40 clocking periods to perform the same multiplication in earlier Intel microprocessors.

Multiplication

Multiplication is performed on bytes, words, or doublewords, and can be signed integer (IMUL) or unsigned integer (MUL). Note that only the 80386 through the Core2 processors multiply 32-bit doublewords. The product after a multiplication is always a double-width product. If two 8-bit numbers are multiplied, they generate a 16-bit product; if two 16-bit numbers are multi-plied, they generate a 32-bit product; and if two 32-bit numbers are multimulti-plied, a 64-bit product is generated. In the 64-bit mode of the Pentium 4, two 64-bit numbers are multiplied to generate a 128-bit product.

Some flag bits (overflow and carry) change when the multiply instruction executes and produce predictable outcomes. The other flags also change, but their results are unpredictable and therefore are unused. In an 8-bit multiplication, if the most significant 8 bits of the result are zero, both C and O flag bits equal zero. These flag bits show that the result is 8 bits wide (C = 0) or 16 bits wide (C = 1). In a 16-bit multiplication, if the most significant 16-bits part of

TABLE 5–8 Example 8-bit multiplication instructions.

Assembly Language Operation

MUL CL AL is multiplied by CL; the unsigned product is in AX IMUL DH AL is multiplied by DH; the signed product is in AX

IMUL BYTE PTR[BX] AL is multiplied by the byte contents of the data segment memory location addressed by BX; the signed product is in AX

MUL TEMP AL is multiplied by the byte contents of data segment memory location TEMP; the unsigned product is in AX

the product is 0, both C and O clear to zero. In a 32-bit multiplication, both C and O indicate that the most significant 32 bits of the product are zero.

8-Bit Multiplication. With 8-bit multiplication, the multiplicand is always in the AL register, whether signed or unsigned. The multiplier can be any 8-bit register or any memory location.

Immediate multiplication is not allowed unless the special signed immediate multiplication instruction, discussed later in this section, appears in a program. The multiplication instruction contains one operand because it always multiplies the operand times the contents of register AL.

An example is the MUL BL instruction, which multiplies the unsigned contents of AL by the unsigned contents of BL. After the multiplication, the unsigned product is placed in AX—a double-width product. Table 5–8 illustrates some 8-bit multiplication instructions.

Suppose that BL and CL each contain two 8-bit unsigned numbers, and these numbers must be multiplied to form a 16-bit product stored in DX. This procedure cannot be accom-plished by a single instruction because we can only multiply a number times the AL register for an 8-bit multiplication. Example 5–13 shows a short program that generates . This example loads register BL and CL with example data 5 and 10. The product, a 50, moves into DX from AX after the multiplication by using the MOV DX,AX instruction.

EXAMPLE 5–13

0000 B3 05 MOV BL,5 ;load data 0002 B1 0A MOV CL,10

0004 8A C1 MOV AL,CL ;position data 0006 F6 E3 MUL BL ;multiply

0008 8B D0 MOV DX,AX ;position product

For signed multiplication, the product is in binary form, if positive, and in two’s comple-ment form, if negative. These are the same forms used to store all positive and negative signed numbers used by the microprocessor. If the program of Example 5–13 multiplies two signed numbers, only the MUL instruction is changed to IMUL.

16-Bit Multiplication. Word multiplication is very similar to byte multiplication. The difference is that AX contains the multiplicand instead of AL, and the 32-bit product appears in DX–AX instead of AX. The DX register always contains the most significant 16 bits of the product, and AX contains the least significant 16 bits. As with 8-bit multiplication, the choice of the multiplier is up to the programmer. Table 5–9 shows several different 16-bit multiplication instructions.

A Special Immediate 16-Bit Multiplication. The 8086/8088 microprocessors could not per-form immediate multiplication; the 80186 through the Core2 processors can do so by using a special version of the multiply instruction. Immediate multiplication must be signed multipli-cation, and the instruction format is different because it contains three operands. The first operand is the 16-bit destination register; the second operand is a register or memory location DX = BL * CL

TABLE 5–9 Example 16-bit multiplication instructions.

Assembly Language Operation

MUL CX AX is multiplied by CX; the unsigned product is in DX–AX IMUL DI AX is multiplied by DI; the signed product is in DX–AX

MUL WORD PTR[SI] AX is multiplied by the word contents of the data segment memory location addressed by SI; the unsigned product is in DX–AX

TABLE 5–10 Example 32-bit multiplication instructions.

Assembly Language Operation

MUL ECX EAX is multiplied by ECX; the unsigned product is in EDX–EAX IMUL EDI EAX is multiplied by EDI; the signed product is in EDX–EAX MUL DWORD PTR[ESI] EAX is multiplied by the doubleword contents of the data segment

memory location address by ESI; the unsigned product is in EDX–EAX

that contains the 16-bit multiplicand; and the third operand is either 8-bit or 16-bit immediate data used as the multiplier.

The IMUL CX,DX,12H instruction multiplies 12H times DX and leaves a 16-bit signed product in CX. If the immediate data are 8 bits, they sign-extend into a 16-bit number before the multiplication occurs. Another example is IMUL BX,NUMBER,1000H, which multiplies NUM-BER times 1000H and leaves the product in BX. Both the destination and multiplicand must be 16-bit numbers. Although this is immediate multiplication, the restrictions placed upon it limit its utility, especially the fact that it is a signed multiplication and the product is 16 bits wide.

32-Bit Multiplication. In the 80386 and above, 32-bit multiplication is allowed because these microprocessors contain 32-bit registers. As with 8- and 16-bit multiplication, 32-bit multiplica-tion can be signed or unsigned by using the IMUL and MUL instrucmultiplica-tions. With 32-bit multipli-cation, the contents of EAX are multiplied by the operand specified with the instruction. The product (64 bits wide) is found in EDX–EAX, where EAX contains the least significant 32 bits of the product. Table 5–10 lists some of the 32-bit multiplication instructions found in the 80386 and above instruction set.

64-Bit Multiplication. The result of a 64-bit multiplication in the Pentium 4 appears in the RDX:RAX register pair as a 128-bit product. Although multiplication of this size is relatively rare, the Pentium 4 and Core2 can perform it on both signed and unsigned numbers. Table 5–11 shows a few examples of this high precision multiplication.

TABLE 5–11 Example 64-bit multiplication instructions.

Assembly Language Operation

MUL RCX RAX is multiplied by RCX; the unsigned product is in RDX–RAX IMUL RDI RAX is multiplied by RDI; the signed product is in RDX–RAX MUL QWORD PTR[RSI] RAX is multiplied by the quadword contents of the memory

location address by RSI; the unsigned product is in RDX–RAX

TABLE 5–12 Example 8-bit division instructions.

Assembly Language Operation

DIV CL AX is divided by CL; the unsigned quotient is in AL and the unsigned remainder is in AH

IDIV BL AX is divided by BL; the signed quotient is in AL and the signed remainder is in AH

DIV BYTE PTR[BP] AX is divided by the byte contents of the stack segment memory location addressed by BP; the unsigned quotient is in AL and the unsigned remainder is in AH

Division

As with multiplication, division occurs on 8- or 16-bit numbers in the 8086–80286 microproces-sors, and on 32-bit numbers in the 80386 and above microprocessor. These numbers are signed (IDIV) or unsigned (DIV) integers. The dividend is always a double-width dividend that is divided by the operand. This means that an 8-bit division divides a 16-bit number by an 8-bit number; a 16-bit division divides a 32-bit number by a 16-bit number; and a 32-bit division divides a 64-bit number by a 32-bit number. There is no immediate division instruction available to any microprocessor. In the 64-bit mode of the Pentium 4 and Core2, a 64-bit division divides a 128-bit number by a 64-bit number.

None of the flag bits change predictably for a division. A division can result in two differ-ent types of errors; one is an attempt to divide by zero and the other is a divide overflow. A divide overflow occurs when a small number divides into a large number. For example, suppose that and that it is divided by 2. Because the quotient for an 8-bit division appears in AL, the result of 1500 causes a divide overflow because the 1500 does not fit into AL. In either case, the microprocessor generates an interrupt if a divide error occurs. In most systems, a divide error interrupt displays an error message on the video screen. The divide error interrupt and all other interrupts for the microprocessor are explained in Chapter 6.

8-Bit Division. An 8-bit division uses the AX register to store the dividend that is divided by the contents of any 8-bit register or memory location. The quotient moves into AL after the divi-sion with AH containing a whole number remainder. For a signed dividivi-sion, the quotient is posi-tive or negaposi-tive; the remainder always assumes the sign of the dividend and is always an integer.

For example, if and and the IDIV BL instruction

exe-cutes, . This represents a quotient of with a remainder of 1 (AH). If, on the other hand, a is divided by , the result will be a quotient of with a remain-der of . Table 5–12 lists some of the 8-bit division instructions.

With 8-bit division, the numbers are usually 8 bits wide. This means that one of them, the dividend, must be converted to a 16-bit wide number in AX. This is accomplished differ-ently for signed and unsigned numbers. For the unsigned number, the most significant 8 bits must be cleared to zero (zero-extended). The MOVZX instruction described in Chapter 4 can be used to zero-extend a number in the 80386 through the Core2 processors. For signed num-bers, the least significant 8 bits are sign-extended into the most significant 8 bits. In the micro-processor, a special instruction sign-extends AL into AH, or converts an 8-bit signed number in AL into a 16-bit signed number in AX. The CBW (convert byte to word) instruction per-forms this conversion. In the 80386 through the Core2, a MOVSX instruction (see Chapter 4) sign-extends a number.

–1 1AH2 –16 +3 – 5 1AL2 –5 1AL2

AX = 01FBH

BL = 0FDH1–32 AX = 0010H 1+162

AX = 3000

TABLE 5–13 Example 16-bit division instructions.

Assembly Language Operation

DIV CX DX–AX is divided by CX; the unsigned quotient is AX and the unsigned remainder is in DX

IDIV SI DX–AX is divided by SI; the signed quotient is in AX and the signed remainder is in DX

DIV NUMB DX–AX is divided by the word contents of data segment memory NUMB; the unsigned quotient is in AX and the unsigned

remainder is in DX EXAMPLE 5–14

0000 A0 0000 R MOV AL,NUMB ;get NUMB 0003 B4 00 MOV AH,0 ;zero-extend 0005 F6 36 0002 R DIV NUMB1 ;divide by NUMB1 0009 A2 0003 R MOV ANSQ,AL ;save quotient 000C 88 26 0004 R MOV ANSR,AH ;save remainder

Example 5–14 illustrates a short program that divides the unsigned byte contents of mem-ory location NUMB by the unsigned contents of memmem-ory location NUMB1. Here, the quotient is stored in location ANSQ and the remainder is stored in location ANSR. Notice how the contents of location NUMB are retrieved from memory and then zero-extended to form a 16-bit unsigned number for the dividend.

16-Bit Division. Sixteen-bit division is similar to 8-bit division, except that instead of dividing into AX, the 16-bit number is divided into DX–AX, a 32-bit dividend. The quotient appears in AX and the remainder appears in DX after a 16-bit division. Table 5–13 lists some of the 16-bit division instructions.

As with 8-bit division, numbers must often be converted to the proper form for the dividend.

If a 16-bit unsigned number is placed in AX, DX must be cleared to zero. In the 80386 and above, the number is zero-extended by using the MOVZX instruction. If AX is a 16-bit signed number, the CWD (convert word to doubleword) instruction sign-extends it into a signed 32-bit number. If the 80386 and above is available, the MOVSX instruction can also be used to sign-extend a number.

EXAMPLE 5–15

0000 B8 FF9C MOV AX,–100 ;load a –100 0003 B9 0009 MOV CX,9 ;load +9 0006 99 CWD ;sign-extend 0007 F7 F9 IDIV CX

Example 5–15 shows the division of two 16-bit signed numbers. Here, in AX is divided by in CX. The CWD instruction converts the in AX to in DX–AX before the division. After the division, the results appear in DX–AX as a quotient of in AX and a remainder of in DX.

32-Bit Division. The 80386 through the Pentium 4 processors perform 32-bit division on signed or unsigned numbers. The 64-bit contents of EDX–EAX are divided by the operand spec-ified by the instruction, leaving a 32-bit quotient in EAX and a 32-bit remainder in EDX. Other than the size of the registers, this instruction functions in the same manner as the 8- and 16-bit divisions. Table 5–14 shows some 32-bit division instructions. The CDQ (convert doubleword to quadword) instruction is used before a signed division to convert the 32-bit contents of EAX into a 64-bit signed number in EDX–EAX.

–1 –100 –100 –11

+9 –100

TABLE 5–14 Example 32-bit division instructions.

Assembly Language Operation

DIV ECX EDX–EAX is divided by ECX; the unsigned quotient is in EAX and the unsigned remainder is in EDX

IDIV DATA4 EDX–EAX is divided by the doubleword contents in data segment memory location DATA4; the signed quotient is in EAX and the signed remainder is in EDX

DIV DWORD PTR[EDI] EDX–EAX is divided by the doubleword contents of the data segment memory location addressed by EDI; the unsigned quotient is in EAX and the unsigned remainder is in EDX

The Remainder. What is done with the remainder after a division? There are a few possible choices. The remainder could be used to round the quotient or just dropped to truncate the quo-tient. If the division is unsigned, rounding requires that the remainder be compared with half the divisor to decide whether to round up the quotient. The remainder could also be converted to a fractional remainder.

EXAMPLE 5–16

0000 F6 F3 DIV BL ;divide

0002 02 E4 ADD AH,AH ;double remainder 0004 3A E3 CMP AH,BL ;test for rounding 0006 72 02 JB NEXT ;if OK

0008 FE C0 INC AL ;round 000A NEXT:

Example 5–16 shows a sequence of instructions that divide AX by BL and round the unsigned result. This program doubles the remainder before comparing it with BL to decide whether to round the quotient. Here, an INC instruction rounds the contents of AL after the comparison.

Suppose that a fractional remainder is required instead of an integer remainder. A fractional remainder is obtained by saving the quotient. Next, the AL register is cleared to zero. The number remaining in AX is now divided by the original operand to generate a fractional remainder.

EXAMPLE 5–17

0000 B8 000D MOV AX,13 ;load 13 0003 B3 02 MOV BL,2 ;load 2 0005 F6 F3 DIV BL ;13/2

0007 A2 0003 R MOV ANSQ,AL ;save quotient 000A B0 00 MOV AL,0 ;clear AL

000C F6 F3 DIV BL ;generate remainder 000E A2 0004 R MOV ANSR,AL ;save remainder

Example 5–17 shows how 13 is divided by 2. The 8-bit quotient is saved in memory loca-tion ANSQ, and then AL is cleared. Next, the contents of AX are again divided by 2 to generate a fractional remainder. After the division, the AL register equals 80H. This is 100000002. If the binary point (radix) is placed before the leftmost bit of AL, the fractional remainder in AL is 0.100000002or 0.5 decimal. The remainder is saved in memory location ANSR in this example.

64-Bit Division. The Pentium 4 processor operated in 64-bit mode performs 64-bit division on signed or unsigned numbers. The 64-bit division uses the RDX:RAX register pair to hold the dividend and the quotient is found in RAX and the remainder is in RDX after the division. Table 5–15 illustrates a few 64-bit division instructions.

TABLE 5–15 Example 64-bit division instructions.

Assembly Language Operation

DIV RCX RDX–RAX is divided by RCX; the unsigned quotient is in RAX and the unsigned remainder is in RDX

IDIV DATA4 RDX–RAX is divided by the quadword contents in memory location DATA4; the signed quotient is in RAX and the signed remainder is in RDX

DIV QWORD PTR[RDI] RDX–RAX is divided by the quadword contents of the memory location addressed by RDI; the unsigned quotient is in RAX and the unsigned remainder is in RDX

在文檔中 THE INTEL MICROPROCESSORS (頁 185-191)