Bryand and O'Hallaron Chapter 3 Section 3.5 Arithmetic Instructions Load Effective Address leal 7(%edx,%edx,4),%eax #%eax <= 5*%edx + 7 Practice Problem 3.3 Assume %eax holds the value x and %ecx holds the value y. Fill in the table. ______________ leal 6(%eax),%edx ______________ leal (%eax,%ecx),%edx ______________ leal (%eax,%ecx,4),%edx ______________ leal 7(%eax,%eax,8),%edx ______________ leal 0xA(,%ecx,4),%edx ______________ leal 9(%eax,%ecx,2),%edx Figure 3.7 Integer Arithmetic Operations (unary and binary) Instruction Effect Description leal S, D D <- &S Load effective address incl D D <- D + 1 Increment decl D D <- D - 1 Decrement negl D D <- -D Negate notl D D <- ~D Complement addl S, D D <- D + S Add subl S, D D <- D - S Subtract imull S, D D <- D * S Multiply xorl S, D D <- D ^ S Exclusive-or orl S, D D <- D | S Or andl S, D D <- D & S And sall k, D D <- D << k Left shift shll k, D D <- D << k Left shift (just sall) sarl k, D D <- D >> k Arithmetic right shift shrl k, D D <- D >> k Logical right shift Practice Problem 3.4 Assume the following values Address Value Register Value 0x100 0xFF %eax 0x100 0x104 0xAB %ecx 0x1 0x108 0x13 %edx 0x3 0x10c 0x11 Fill in the table Instruction Destination Value addl %ecx,(%eax) subl %edx,4(%eax) imull $16,(%eax,%edx,4) incl 8(%eax) decl %ecx subl %edx,%eax See Practice Problem 3.5 Shift Instructions The amount of the shift can either be specified by an immediate operand or by the contents of register %cl. If there are two opeands, the first must be either an immediate operand or "%cl". In the one operand version, genrates a shift of one bit. The following program assembles without error. .globl main main: sarl $3,%eax # arithmetic left shift by 3 bits movb $3,%cl sarl %cl,%eax # arithmetic left shift, 3 more bits sarl %eax # arithmetic left shift, 1 more bit ret As we have seen, the C complier frequently replaces multiplications by a constant with shifts and adds. 64-bit Multiplications and Divisions Instruction Effect Description imul S R[%edx]:R[%eax] <- S * R[%eax] Signed full multiply mul S R[%edx]:R[%eax] <- S * R[%eax] Unsigned full multiply cltd R[%edx]:R[%eax] <- SignExtend(R[%eax]) Convert to quad word idivl S R[%edx] <- R[%edx]:R[%eax] mod S Signed divide R[%eax] <- R[%edx]:R[%eax] / S divl S R[%edx] <- R[%edx]:R[%eax] mod S Unsigned divide R[%eax] <- R[%edx]:R[%eax] / S Assumed signed numbers x and y stored a 8 and 12 relative to %ebp. To place the full 64-bit product on the top of the stack: move 8(%ebp),%eax # put x in %eax imull 12(%ebp) # multiply by y pushl %edx #push high-order 32 bits pushl %eax #push low-order 32 bits Is the little endian or bit endian? To store x/y and x%y on the stack: move 8(%ebp),%eax # put x in %eax cltd # sign extend into %edx idivl 12(%ebp) # divide by y pushl %eax # push x / y pushl %eax # push x % y