xorl %edx,%edx Explain why this instruction would be there, even though there are no EXCLUSIVE - OR operators in our C code. What operation in the C program does this instruction implement? 3.5.5 Special Arithmetic Operations Figure 3.8 describes instructions that support generating the full 64-bit product of two 32-bit numbers, as well as integer division. The imull instruction listed in Figure 3.6 is known as the “two-operand” multiply instruction. It gen- erates a 32-bit product from two 32-bit operands, implementing the operations * u and * t described in Sections 2.3.4 and 2.3.5 (pages 61 and 62). Recall that when truncating the product to 32 bits, both un- signed multiply and two’s complement multiply have the same bit-level behavior. IA32 also provides two different “one-operand” multiply instructions to compute the full 64-bit product of two 32-bit values—one for unsigned ( mull ), and one for two’s complement ( imull ) multiplication. For both of these, one argu- ment must be in register %eax , and the other is given as the instruction source operand. The product is then stored in registers %edx (high-order 32 bits) and %eax (low-order 32 bits). Note that although the name imull is used for two distinct multiplication operations, the assembler can tell which one is intended by counting the number of operands. As an example, suppose we have signed numbers x and y stored at positions and relative to %ebp , and we want to store their full 64-bit product as 8 bytes on top of the stack. The code would proceed as follows: x at %ebp +8, y at %ebp +12 1 movl 8(%ebp),%eax Put x in %eax 2 imull 12(%ebp) Multiply by y 3 pushl %edx Push high-order 32 bits 4 pushl %eax Push low-order 32 bits Observe that the order in which we push the two registers is correct for a little-endian machine in which the stack grows toward lower addresses, i.e., the low-order bytes of the product will have lower addresses than the high-order bytes.
110 CHAPTER 3. MACHINE-LEVEL REPRESENTATION OF C PROGRAMS Our earlier table of arithmetic operations (Figure 3.6) does not list any division or modulus operations. These operations are provided by the single-operand divide instructions similar to the single-operand multiply instructions. The signed division instruction idivl takes as dividend the 64-bit quantity in registers %edx (high-order 32 bits) and %eax (low-order 32 bits). The divisor is given as the instruction operand. The instructions store the quotient in register %eax and the remainder in register %edx . The cltd 1 instruction can be used to form the 64-bit dividend from a 32-bit value stored in register %eax . This instruction sign extends %eax into %edx . As an example, suppose we have signed numbers x and y stored in positions and relative to %ebp , and we want to store values x/y and x%y on the stack. The code would proceed as follows: x at %ebp +8, y at %ebp +12 1 movl 8(%ebp),%eax Put x in %eax 2 cltd Sign extend into %edx 3 idivl 12(%ebp) Divide by y 4 pushl %eax Push x / y 5 pushl %edx Push x % y The divl instruction performs unsigned division. Typically register %edx is set to 0 beforehand.
You've reached the end of your free preview.
Want to read all 808 pages?