EE25M Introduction to microprocessors original author: Feisal Mohammed updated: 6th February 2002 CLR Part IV ALU and Arithmetic Operations There are several issues connected with the use of arithmetic by computers. The first is the type of numeric data upon which arithmetic operations will be performed, and how such numbers should be represented; the second is the means by which the numbers should be manipulated; and the third is the bit/byte/word-ordering of data within memory to accommodate the representation. In the following notes, we will look at two s complement, binary-coded decimal, and floating point representations of numbers. 10 Two s Complement The most commonly found representation of integer numbers in computers is the two s complement representation. In this representation, the full range of binary numbers (2 n for n bits) is split between positive and negative numbers ( 2 n 1 to 2 n 1 1). Positive numbers are the same as their unsigned representations. To find the representation of a negative number, invert the bits of the unsigned binary representation and then add 1. Using this representation, all subtractive operations become additions with a negative number. Because the uppermost bit of a two s complement number is always 0 for positive numbers 19, and 1 for negative numbers, this bit is often referred to as the sign bit. There are two ways to implement the multiplication of two 8-bit unsigned numbers, one is by repeated addition and the other is via partial sums. These methods will not work for all combinations of two s complement numbers [Sta00, Ch. 8]. Instead Booth s algorithm, a variant of the partial sums method, must be utilised. Division is the opposite of multiplication. In it s simplest form, the divisor may be repeatedly subtracted from the dividend and the quotient incremented each time. A Booths s like partial subtraction method may be employed for signed numbers. Changing the bit width of a two s complement number can be done by sign reduction or extension i.e. removing locations which are the same as the sign bit, or copying the sign bits to any additional bit locations. In practice, representation of a number using more bits involves the use of multiple data words. Because the ALU is generally structured for single data word operations, the addition of multiple-word integer numbers i.e. 16-bit, 24-bit, etc. requires extra work. Let us look at the manipulation (addition, subtraction, multiplication, division) of numbers represented by single and multiple words 20 using the PIC16F877. The following examples assume that the relevant constants have been defined in the included.inc file, and the variables are already declared. 19 Zero is assumed to be a positive number. 20 Use the simulator, code, pencil and paper to work through each of the routines presented to ensure thorough understanding. It is important to work through these exercises in the MPLAB simulator in order to get a good idea of the operation of the PIC (and to catch all the mistakes Cathy made!). It is very difficult to learn the programming without actual hands-on experience.
EE25M 6th February 2002 IV 2 Decrementing a 16-bit variable Given a 16-bit variable with its low byte in countl and high byte in counth, write a routine to decrement it. Decr movf countl,f ; set the Zero flag if countl is zero btfsc STATUS,Z ; countl zero? decrement counth (next instr) decf counth,f decf countl,f ; always decrement countl Test a 16-bit variable for zero Using the same 16-bit variable as before, test it for zero. Iszero movf countl,f ; test for zero in low byte btfsc STATUS,Z ; if not, don t test high byte movf counth,f ; test high byte btfsc STATUS,Z goto Bothzero ; Zero? branch to some appropriate place... 16-bit Addition A simple work around for 16-bit numbers is to simply increment one of the numbers if the Carry is set. For example: ; This routine adds the 16-bit number in datalo and datahi, to the ; 16-bit number is resultlo and resulthi, leaving the answer in ; resultlo and resulthi Add16 movf datalo,w ; W = datalo addwf resultlo,f ; resultlo = resultlo + W movf datahi,w ; W = datahi btfsc STATUS,C ; If no carry skip incf resulthi,f ; If carry, add 1 to result addwf resulthi,f ; resulthi = resulthi + W There is a problem with this method because the Carry bit does not accurately reflect the results of the last addition. In particular, if resulthi was 0xFF and the Carry bit was set from the low bytes then after the last addition the Carry bit would be clear and it should be set. This means that this method cannot be scaled up to be used with 24-bit and larger numbers. A slightly longer, but scalable routine that correctly sets the Carry bit on termination is shown below. You should work out the sequence of operations to ensure that you understand the routine. Addgood movf datalo,w ; W = datalo addwf resultlo,f ; resultlo = resultlo + W movf datahi,w ; W = datahi btfsc STATUS,C ; If no carry... incfsz resulthi,f ; if resulthi is 0 after the increment ;... don t do the addition addwf resulthi,w movwf resulthi ; resulthi = resulthi + W
EE25M 6th February 2002 IV 3 16-bit Subtraction Subtraction is very similar to addition, with the inclusion of the borrow. The only difference to look out for is that the PIC16xxx treats the carry bit as a Borrow. Assume that the operation required is R = Q 1 - Q 2, where Q 1 and Q 2 are two 16-bit numbers. This can be accomplished by the following code: Subr movf Q2_lo,W subwf Q1_lo,W ; W = Q1_lo - Q2_lo movwf R_lo btfss STATUS,C ; need to borrow? decf Q1_hi,F ; get it from hi byte movf Q2_hi,W subwf Q1_hi,W ; W = Q1_hi - Q2_hi movwf R_hi Note that the carry flag at the end of the routine will not be set correctly if Q2 hi is 0. An improved routine is as follows Subrgd movf Q2_lo,W subwf Q1_lo,W ; W = Q1_lo - Q2_lo movwf R_lo movf Q2_hi,W btfss STATUS,C ; need to borrow? goto Borrow subwf Q1_hi,W ; W = Q1_hi - Q2_hi movwf R_hi goto Done Borrow subwf Q1_hi,W ; W = Q1_hi - Q2_hi movwf R_hi decf R_hi,F ; do the decrement after Done Extending bit width 8bit > 16bit the positions of the new upper byte. Extension consists of copying the relevant bit into all E8to16 movlw 255 ; make the accumulator 1111 1111 clrf Out_hi ; clear out the upper result byte btfsc In, 7 ; if the top bit of the input byte is 1 movwf Out_hi ; put all ones in the upper result byte movf In,W ; copy the input byte to movwf Out_lo ; the lower result byte
EE25M 6th February 2002 IV 4 8-bit by 8-bit Unsigned Multiplication There are two ways to implement the multiplication of two 8-bit numbers, one is by repeated addition and the other is via partial sums. The first example multiplies M1 by M2 leaving the result in R hi and R lo. It loops through the addition of M2 to itself M1 times. ; 8x8 unsigned multiply routine. ; No checks made for M1 or M2 equal to zero clrf R_hi ; clear result location clrf R_lo clrw M8x8 addwf M2,W ; add M2 to itself btfsc STATUS,C ; if carry set inc R_hi,F ;... increment high byte decfsz M1,F goto M8x8 movwf R_lo This second routine, does the same thing but loops only 8 times instead of M1 times as the previous case. M1 is added to the result which is then shifted. It makes use of the fact that multiplying a number by one results in the same number so all that is required is either addition if the bit, in M2, was one or no addition if it was zero. ; 8x8 unsigned multiply routine. ; No checks made for M1 or M2 equal to zero clrf R_hi ; Clear result location clrf R_lo movlw 0x08 ; setup loop count movwf cntr movf M1,W ; initialize W with M1 Umul rrf M2,F ; rotate into carry to check bits btfsc STATUS,C ; if carry set i.e. bit was 1 addwf R_hi,F ;... we add rrf R_hi,F ; shift over for the next addition rrf R_lo,F decf cntr,f ; check the loop count btfss STATUS,Z goto Umul
EE25M 6th February 2002 IV 5 16-bit by 8-bit Unsigned Division ; 16-bit unsigned division ; Quot = (Div_hi, Div_lo) / Divsor clrf Quot Divide movf Divsor,W ; setup for subtraction subwf Div_lo,F ; Div_lo = Div_lo - Divisor btfss STATUS,C goto Borrow goto Div_2 Borrow movlw 0x01 subwf Div_hi,F ; use subtract instead of decf btfss STATUS,C ;... because it sets the carry goto Done ; generated a borrow so finish Div_2 incf Quot,F ; add one and loop again goto Divide Done Reducing bit width 16bit > 8bit Reduction should only occur if the bits of the upper byte all match the uppermost bit of the lower byte. R16to8 movlw 255 ; make a byte with the btfsc In_lo,7 ; inverted upper bit of the lower byte clrw xorwf In_hi,W ; xor with the upper byte to check if all bits are the same btfss STATUS,Z ; an error (non-zero W) if not the same retlw 255 ; movf In_lo,W ; otherwise truncate and movwf Out retlw 0
EE25M 6th February 2002 IV 6 Exercises 1. Write code to decrement a 16-bit variable and test the result for zero, branching to Bothzero if the result is zero. Can this be done using fewer lines of code and/or faster execution than simply concatenating the two routines shown previously? 2. Why does -7/3 yield a different remainder to 7/-3? 3. Design an algorithm and implement it in PIC assembly language to perform unsigned division of a 24-bit number by an 8-bit number and produce a 16-bit quotient and 8-bit remainder. 4. Design an algorithm that works more efficiently than repeated subtraction for unsigned 8-bit by 8-bit division. Implement it in PIC assembly language. 5. Implement Booth s algorithm for two signed 8 bit numbers in PIC assembly language. It is presumed that the result with by 16 bits wide. 6. Design a Booth s-like algorithm for the division of a signed 16 bit number by a signed 8 bit number, and implement it in PIC assembly language. 7. Presuming a two s complement 8-bit integer representation, write an algorithm and implement it in PIC assembly language to count the number of negative integers in a set of twenty numbers starting at address 30h. [Past Paper 2001, No. 1(c)] 8. Write an algorithm and implement it in PIC assembly language to subtract two 24-bit numbers, Q 1 and Q 2, and store the result in R. Ensure that the carry flag reflects the result of the subtraction. [Past Paper 2001, No. 2] CourseWork A - 10% Using PIC Assembly, implement Booth s algorithm for the multiplication of two 16-bit signed integers. This exercise is to be tested on the simulator, and demonstrated to the lab demonstrator in week 5 (begins 18/2/02). A report containing: the algorithm design, printout of commented code, copy of the code (*.asm; *.hex) on disk, and a set of 5 test cases and the results should be submitted by the end of week 6 (1/3/02). References [Sta00] William Stallings. Computer Architecture and Organization. Prentice-Hall, Inc., 5th edition, 2000.
EE25M 6th February 2002 IV 7 11 Binary Coded Decimal Binary coded decimal representation of numbers, uses a 4 bit binary number to represent the decimal digits 0-9. It is clearly an inefficient representation, as 6 of the numbers which could be represnted by 4 bits are never used. The advantage of using such a scheme lies in the fact that most human I/O involves the use of decimal numbers. The use of BCD reduces the overhead of conversion at the interface-level. The disadvantage is that mathematical operations become more complex, as the manipulation of individual binary digits may yield an invalid 4 bit BCD code. Further there is no accomodation for signed quantities. Subsequently BCD arithmetic operations are generally restricted to addition and subtraction of unsigned quantities. In packed BCD, two digits are continued within a single byte. Other representations pad the extra bits in the byte/word (i.e. leave the upper bits of the data word either unused or filled with a particular prefix) e.g. 7 bit ASCII character codes. Packed BCD Validity checking Adding 6 to a 4-bit nibble produces a carry out of that nibble if the nibble is an invalid BCD code. The following s 1 in the working register if either code in Reg are invalid. PBCDchk movlw 0x66 addf Reg,W btfsc STATUS,C retlw 1 btfsc STATUS,DC retlw 1 retlw 0 Packed BCD Addition The addition of BCD numbers involves consideration of the decimal carry. The addition plus 6 to each nibble will produce a carry exactly when the decimal addition of two digits in the operands would produce a carry, and these are the carries we are concerned with. But the digits in positions that did not produce a carry will contain an excess 6. The problem, then, is to remove the extra 6 from each digit that did not generate a carry. The following routine leaves the carry set if the upper digit overflows: PBCDadd movlw 0x66 addf RegA,W addf RegB,W rrf Out,F btfss STATUS,DC addlw -0x06 btfss Out,7 addlw -0x60 rlf Out,F movwf Out From: Scott Dattalo (http://www.piclist.com/techref/microchip/math/add/bcdp2.htm)
EE25M 6th February 2002 IV 8 Packed BCD Subtraction Similarly to two s complement arithmetic for binary number, subtraction of decimal numbers can be performed by adding the ten s complement (subtract from all nines and add 1) e.g. 8 10 2 10 8 10 16 10 08 10 + 98 10 08 10 + 85 10 1 06 10 93 10 6 10 8 10 Note that 0 to 99 represents the numbers +49 to -50 in ten s complement notation. The following code produces the ten s complement of a packed BCD number: PBCDCmp movlw 0x99 ; movwf Out ; movf In ; subwf Out,F ; Out=0x99-In incf Out,F Packed BCD Single Digit extraction mask may be used: To extract a single digit from a BCD number, a bit PBCDext movlw 0xF0 andwf In,W movf Nibble_hi movlw 0x0F andwf In,W movf Nibble_lo Conversion BCD to unsigned binary To convert from BCD to an unsigned binary, multiply the upper nibble by ten and add the lower nibble. This can be done by shifting the upper nibble right 3 places (multiply by 8), adding the upper nibble shifted 1 place (multiply by 2) and adding the lower nibble. PBCDbin rrf In,W andlw 0x78 ; 0111 1000 movwf Out bcf STATUS,C rrf Out,F rrf Out,F addwf Out,F movlw In andlw 0x0F addwf Out,F
EE25M 6th February 2002 IV 9 Conversion unsigned binary to BCD To convert binary to BCD, check that the 7th bit is not used, and set the carry if the number exceeds 99(i.e. between 99 and 128). BinPBCD btfss In,7 ; check if > 128 retlw 1 ; an error clrf Out movlw 156 ; Check if the number will overflow addwf In,W ; rrf Out,F ; Store the Carry in Out movlw 100 ; subtract 100 if needed btfss Out,7 ; subwf In,W ; iorwf Out,F ; Store the reduced number swapf Out,W ; sort out the bottom bits addwf Out,W andlw 0x0F btfsc STATUS,DC ; correct for the DC addlw 0x10 btfsc Out,4 ; correct for bit 4 addlw 0x06 btfsc Out,7 ; correct for the Carry stored in bit 8 sublw 0x08 addlw 6 ; make sure lower nibble is 0-9 btfss STATUS,DC addlw -6 btfsc Out,6 ; now the upper bits addlw 0x60 ; If the 64 bit is on store BCD 60 btfsc Out,5 addlw 0x30 ; If the 32 bit is on add BCD 30 btfsc Out,4 addlw 0x10 ; If the 16 bit is on add BCD 10 rlf Out,F movwf Out ; restore the carry, set Out and
EE25M 6th February 2002 IV 10 Exercises 1. Many CPU s provide logic for performing arithmetic on packed decimal numbers. Although he rules for decimal arithmetic are similar to those for binary operations, the decimal results may require some corrections to the individual digits if binary logic is used. Consider the decimal addition of two unsigned numbers. If each number consists of N digits, then there are 4N bits in each number. The two numbers are to be added using a binary adder. Suggest a simple rule for correcting the result. Perform addition in this fashion on the numbers 1698 and 1786. [Sta00, 9.1] 2. The tens complement of the decimal number X is defined to be 10N X, where N is the number of digits in the number. Describe the use of tens complement representation to perform decimal subtraction. Illustrate the procedure by subtracting (0326) 10 from (0736) 10. [Sta00, 9.2] What purpose does ten s complement arithmetic serve in BCD arithmetic? 3. BCD is not the only means of representing decimal numbers. The ASCII 21 character set defines a representation of characters as 7 bit numbers. The digit characters 0 through 9 are represented as 011 0000 thru 011 1001. Using this information write routines to correctly add and subtract two ASCII digits. (Note: The carry flag should be set for overflow, or no borrow respectively) References [Sta00] William Stallings. Computer Architecture and Organization. Prentice-Hall, Inc., 5th edition, 2000. 21 American Standard Code for Information Interchange