cs3843 syllabus outline lecture notes programming assignments recitations homework set up Integer Arithmetic and Shifting Instructions We will discuss operations requiring only one operand operations requiring two operands operations requiring special operands Overview of the Machine instruction categories Arithmetic - 2 byte and 4 byte addS operand1, operand2 subS operand1, operand2 imulS operand1, operand2* idivS operand* incS operand decS operand negS operand add op1 to op2 subtract op1 from op2 multiply op2 by op1 divide by operand increment the operand decrement the operand negate the operand Shift salS k,reg shift arithmetic left sarS k,reg shift arithmetic right shlS k,reg shift logical left shrS k,reg shift logical right Load Effective Address - load the address instead of the value from an address leaS source, dest Examples: addl 4(%ebp), %edx incw %dx #Adds the value at the address computed by #an offset of 4 from the value of ebp to #the value of edx. The result is stored #in edx. #Increment the 2 byte value in dx leal lresult,%edx #Move the address of lresult to edx sarl $3, %edx #Arithmetic shift of the long value in edx #3 bits to the right Note: S is the size and must be one of b byte (1 byte) w word (2 bytes) l long (4 bytes) q quad words (8 bytes) W for word is based on the old machines where a word was 2 bytes. Operations Requiring Only One Operand The operand can be a register or a memory reference. incS operand increment the value of length S in the Assume the following assembly language snippet: iValA: .long 0xA destination. This does not change CF. decS operand decrement the value of length S in the destination. This does not change CF. notS operand do a ones' comp on the value in the destination negS operand do a two's comp on the value in the destination. Sets CF to 1 unless the operand's value is zero. Operations Requiring Two Operands These operations use the value of the second operand and store the result in the second operand. iValB: .long 0x40 … movl iValA,%edx incl %edx incl iValB mov1 $iValA,%eax incl 4(%eax) not1 iValB #iValA -> edx #edx ++ #iValB ++ #Increment the value at addr(iValA)+4 #1's comp iValB placing the result in iValB Add and Subtract addS operand1, operand2 subS operand1, operand2 Shift salS k,reg sarS k,reg shlS k,reg shrS k,reg add op1 to op2. This can change OF, ZF, and/or SF. subtract op1 from op2. This can change OF, ZF, and/or SF. shift arithmetic left shift arithmetic right shift logical left shift logical right Operations Requiring Special Operands - Multiply Some registers are implicitly used. imulS also sets OF. For S=w (2 bytes) multiplicand must be %ax multiplier can be a reg or memory reference for a long product (the result) will be in %dx(high order) and %ax (low order) For S=l (4 bytes), multiplicand must be %eax multiplier can be a reg or memory reference for a long product (the result) will be in %edx(high order) and %eax (low order) %eax multiplier Example M-1: 4-byte multiply 0x12345 by 0x1000 movl $0x12345, %eax movl $0x1000, %ebx imull %ebx The result in %edx:%eax is 00000000 12345000 and OF=0. Example M-2: 2-byte multiply 0x2000 by 0x0100 Assume val1 is 0x2000 and val2 is 0x0100. movw val1, %ax imulw val2 The result is %dx:%ax is 0020 0000 and OF=1 Example M-3: 2-byte multiply 0x40 by -100 Assume val1 is 0x40 and val2 is -100 (decimal). movW val1, %ax imulW val2 What is %dx:%ax? -100 is -(0x64) = FF9C 0xFF9C * 0x0040 = FFFFE700 and OF=0 since the sign propagated Note: this course does NOT require knowing how to multiply integer values. It does require understanding shifts, add, and/or subtracts to handle multiplication by some constants. Why are two registers needed for the result? Operations Requiring Special Operands - Divide Some registers are implicitly used. idivS also sets OF. For S=w (2 bytes) dividend must be %dx (high order) and %ax (low order) divisor can be a reg or memory reference for a long quotient is in %ax and remainder is in %dx For S=l (4 bytes), dividend must be %edx (high order) and %eax (low order) divisor can be a reg or memory reference for a long quotient is in %eax and remainder is in %edx %edx %eax %eax (quotient) %edx (remainder) = divisor Since the dividend is two registers, we must be able to propagate the sign from eax to edx (and ax to dx): cwtd convert word to double word propagates the sign in %ax to %dx cltd convert long to double long propagates he sign in %eax to %edx Division examples Example D-1: 2-byte divide 0x4007 by 0x100 movw $0x4007, %ax #load the low end of dividend movw 0, %dx #clear the high end of dividend idivw $0x100 #divide by 0x100 Quotient (%ax) is 0x0040. Remainder (%dx) is 0x0007. Example D-2: 2-byte divide movw shTotalCnt, %ax cwtd idivw shCourseCnt shTotalCnt by shCourseCnt #load the low end of dividend #propagate sign to high end #divide by shCOurseCnt Example D-3: 4-byte divide lTotal by 0x200 movl lTotal, %eax #load the low end of dividend cltd #propagate sign to high end idivl $0x200 #divide by 0x200 Quotient will be in %eax and remainder in %edx.