📄 chapter 5 expressions -- valvano.htm
字号:
<P><FONT face="Times New Roman,Times">The first input parameter is an
expression, Expr1, which yields a boolean (0 for false, not zero for true).
Expr2 and Expr3 return values that are regular numbers. The selection operator
will return the result of Expr2 if the value of Expr1 is true, and will return
the result of Expr3 if the value of Expr1 is false. The type of the expression
is determined by the types of Expr2 and Expr3. If Expr2 and Expr3 have different
types, then the usual promotion is applied. The resulting time is determined at
compile time, in a similar manner as the Expr2+Expr3 operation, and not at run
time depending on the value of Expr1. The following two subroutines have
identical functions. </FONT><FONT face="Courier,Courier New" color=#008000
size=2><BR></FONT><CODE>int a,b;</CODE><FONT face="Courier,Courier New"
color=#008000 size=2><BR></FONT><CODE>void sub1(void){ <BR> a =
(b==1) ? 10 : 1; <BR>}<BR>void sub2(void){ <BR> if(b==1)
<BR> a=10; <BR> else
<BR> a=1; <BR>}</CODE></P>
<P><I>Listing 5-8: Examples of the selection operator</I></P>
<P> </P>
<P><I><B><FONT face=Helvetica,Arial><A name=OVERFLOW></A>Arithmetic Overflow and
Underflow</FONT></B></I></P>
<P>An important issue when performing arithmetic calculations on integer values
is the problem of underflow and overflow. Arithmetic operations include
addition, subtraction, multiplication, division and shifting. Overflow and
underflow errors can occur during all of these operations. In assembly language
the programmer is warned that an error has occurred because the processor will
set condition code bits after each of these operations. Unfortunately, the C
compiler provides no direct access to these error codes, so we must develop
careful strategies for dealing with overflow and underflow. It is important to
remember that arithmetic operations (addition, subtraction, multiplication,
division, and shifting) have constraints when performed with finite precision on
a microcomputer. An overflow error occurs when the result of an arithmetic
operation can not fit into the finite precision of the result. We will study
addition and subtraction operations in detail, but the techniques for dealing
with overflow and underflow will apply to the other arithmetic operations as
well. We will consider two approaches</P>
<DIR>
<P>avoiding the error<BR>detecting the error then correcting the
result</P></DIR>
<P>For example when two 8 bit numbers are added, the sum may not fit back into
the 8 bit result. We saw earlier that the same digital hardware (instructions)
could be used to add and subtract unsigned and signed numbers. Unfortunately, we
will have to design separate overflow detection for signed and unsigned addition
and subtraction.</P>
<P>All microcomputers have a condition code register which contain bits which
specify the status of the most recent operation. In this section, we will
introduce 4 condition code bits common to most microcomputers. If the two inputs
to an addition or subtraction operation are considered as unsigned, then the C
bit (carry) will be set if the result does not fit. In other words, after an
unsigned addition, the C bit is set if the answer is wrong. If the two inputs to
an addition or subtraction operation are considered as signed, then the V bit
(overflow) will be set if the result does not fit. In other words, after a
signed addition, the V bit is set if the answer is wrong. The Motorola 6805 does
not have a V bit, therefore it will be difficult to check for errors after an
operation on signed numbers.</P>
<P><FONT face=Monaco size=2>bit</FONT><CODE> </CODE><FONT face=Monaco
size=2>name</FONT><CODE> </CODE><FONT
face=Monaco size=2>meaning after addition or
subtraction<BR>N</FONT><CODE> </CODE><FONT face=Monaco
size=2>negative</FONT><CODE> </CODE><FONT face=Monaco
size=2>result is negative<BR>Z</FONT><CODE> </CODE><FONT
face=Monaco
size=2>zero</FONT><CODE> </CODE><FONT
face=Monaco size=2>result is
zero<BR>V</FONT><CODE> </CODE><FONT face=Monaco
size=2>overflow</FONT><CODE> </CODE><FONT face=Monaco
size=2>signed overflow<BR>C</FONT><CODE> </CODE><FONT
face=Monaco
size=2>carry</FONT><CODE> </CODE><FONT
face=Monaco size=2>unsigned overflow</FONT></P>
<ADDRESS>Table 5.9. Condition code bits contain the status of the previous
arithmetic or logical operation.</ADDRESS>
<P>For an 8 bit unsigned number, there are only 256 possible values, 0 to 255.
We can think of the numbers as positions along a circle. There is a
discontinuity at the 0|255 interface, everywhere else adjacent numbers differ by
&plusmn;1. If we add two unsigned numbers, we start at the position of the
first number a move in a clockwise direction the number of steps equal to the
second number. For example, if 96+64 is performed in 8 bit unsigned precision,
the correct result of 160 is obtained. In this case, the carry bit will be 0
signifying the answer is correct. On the other hand, if 224+64 is performed in 8
bit unsigned precision, the incorrect result of 32 is obtained. In this case,
the carry bit will be 1, signifying the answer is wrong.</P>
<P><IMG height=166 src="Chapter 5 Expressions -- Valvano.files/Image25.gif"
width=430></P>
<P><I>Figure 5-1: 8 bit unsigned addition.</I></P>
<P>For subtraction, we start at the position of the first number a move in a
counterclockwise direction the number of steps equal to the second number. For
example, if 160-64 is performed in 8 bit unsigned precision, the correct result
of 96 is obtained (carry bit will be 0.) On the other hand, if 32-64 is
performed in 8 bit unsigned precision, the incorrect result of 224 is obtained
(carry bit will be 1.) </P>
<P> </P>
<P><IMG height=169 src="Chapter 5 Expressions -- Valvano.files/Image26.gif"
width=428></P>
<P><I>Figure 5-2: 8 bit unsigned subtraction.</I></P>
<P>In general, we see that the carry bit is set when we cross over from 255 to 0
while adding or cross over from 0 to 255 while subtracting. </P>
<P><B><I>Observation: The carry bit, C, is set after an unsigned add or subtract
when the result is incorrect.</I></B> </P>
<P>For an 8 bit signed number, the possible values range from -128 to 127. Again
there is a discontinuity, but this time it exists at the -128|127 interface,
everywhere else adjacent numbers differ by &plusmn;1. The meanings of the
numbers with bit 7=1 are different from unsigned, but we add and subtract signed
numbers on the number wheel in a similar way (e.g., addition of a positive
number moves clockwise.) Adding a negative number is the same as subtracting a
positive number hence this operation would cause a counterclockwise motion. For
example, if -32+64 is performed, the correct result of 32 is obtained. In this
case, the overflow bit will be 0 signifying the answer is correct. On the other
hand, if 96+64 is performed, the incorrect result of -96 is obtained. In this
case, the overflow bit will be 1 signifying the answer is wrong.</P>
<P><IMG height=176 src="Chapter 5 Expressions -- Valvano.files/Image27.gif"
width=430></P>
<P><I>Figure 5-3: 8 bit signed addition.</I></P>
<P><BR>For subtracting signed numbers, we again move in a counterclockwise
direction. Subtracting a negative number is the same as adding a positive number
hence this operation would cause a clockwise motion. For example, if 32-64 is
performed, the correct result of -32 is obtained (overflow bit will be 0.) On
the other hand, if -96-64 is performed, the incorrect result of 96 is obtained
(overflow bit will be 1.) </P>
<P><IMG height=174 src="Chapter 5 Expressions -- Valvano.files/Image28.gif"
width=424></P>
<P><I>Figure 5-4: 8 bit signed subtraction.</I></P>
<P>In general, we see that the overflow bit is set when we cross over from 127
to -128 while adding or cross over from -128 to 127 while subtracting.</P>
<P><B><I>Observation: The overflow bit, V, is set after a signed add or subtract
when the result is incorrect. </I></B></P>
<P>Another way to determine the overflow bit after an addition is to consider
the carry out of bit 6. The V bit will be set of there is a carry out of bit 6
(into bit 7) but no carry out of bit 7 (into the C bit). It is also set if there
is no carry out of bit 6 but there is a carry out of bit 7. Let
X7,X6,X5,X4,X3,X2,X1,X0 and M7,M6,M5,M4,M3,M2,M1,M0 be the individual binary
bits of the two 8 bit numbers which are to be added, and let
R7,R6,R5,R4,R3,R2,R1,R0 be individual binary bits of the 8 bit sum. Then, the 4
condition code bits after an addition are shown in Table 5.10.</P>
<P> </P>
<P><IMG height=135 src="Chapter 5 Expressions -- Valvano.files/Image29.gif"
width=413></P>
<ADDRESS>Table 5.10. Condition code bits after an 8 bit addition
operation.</ADDRESS>
<P>Let the result R be the result of the subtraction X-M. Then, the 4 condition
code bits are shown in Table 5.11.</P>
<P><IMG height=135 src="Chapter 5 Expressions -- Valvano.files/Image30.gif"
width=413></P>
<ADDRESS>Table 5-11. Condition code bits after an 8 bit subtraction
operation.</ADDRESS>
<P><BR><B><I>Common Error: Ignoring overflow (signed or unsigned) can result in
significant errors.</I></B></P>
<P><B><I>Observation: Microcomputers have two sets of conditional branch
instructions (if statements) which make program decisions based on either the C
or V bit. </I></B></P>
<P><B><I>Common Error: An error will occur if you unsigned conditional branch
instructions (if statements) after operating on signed numbers, and vice-versa.
</I></B></P>
<P>There are some applications where arithmetic errors are not possible. For
example if we had two 8 bit unsigned numbers that we knew were in the range of 0
to 100, then no overflow is possible when they are added together.</P>
<P>Typically the numbers we are processing are either signed or unsigned (but
not both), so we need only consider the corresponding C or V bit (but not both
the C and V bits at the same time.) In other words, if the two numbers are
unsigned, then we look at the C bit and ignore the V bit. Conversely, if the two
numbers are signed, then we look at the V bit and ignore the C bit. There are
two appropriate mechanisms to deal with the potential for arithmetic errors when
adding and subtracting. The first mechanism, used by most compilers, is called
promotion. Promotion involves increasing the precision of the input numbers, and
performing the operation at that higher precision. An error can still occur if
the result is stored back into the smaller precision. Fortunately, the program
has the ability to test the intermediate result to see if it will fit into the
smaller precision. To promote an unsigned number we add zero’s to the left side.
In a previous example, we added the unsigned 8 bit 224 to 64, and got the wrong
result of 32. With promotion we first convert the two 8 bit numbers to 16 bits,
then add.</P>
<P>We can check the 16 bit intermediate result (e.g., 228) to see if the answer
will fit back into the 8 bit result. In the following flowchart, X and M are 8
bit unsigned inputs, X16, M16, and R16 are 16 bit intermediate values, and R is
an 8 bit unsigned output. The oval symbol represents the entry and exit points,
the rectangle is used for calculations, and the diamond shows a decision. Later
in the book we will use parallelograms and trapezoids to perform input/output
functions.</P>
<P><IMG height=199 src="Chapter 5 Expressions -- Valvano.files/Image32.gif"
width=337></P>
<ADDRESS>Figure 5-5: Promotion can be used to avoid overflow and
underflow.</ADDRESS>
<P>To promote a signed number, we duplicate the sign bit as we add binary digits
to the left side. Earlier, we performed the 8 bit signed operation -96-64 and
got a signed overflow. With promotion we first convert the two numbers to 16
bits, then subtract.</P>
<P><IMG height=60 src="Chapter 5 Expressions -- Valvano.files/Image33.gif"
width=293></P>
<P> </P>
<P>We can check the 16 bit intermediate result (e.g., -160) to see if the answer
will fit back into the 8 bit result. In the following flowchart, X and M are 8
bit signed inputs, X16, M16, and R16 are 16 bit signed intermediate values, and
R is an 8 bit signed output.</P>
<P><IMG height=209 src="Chapter 5 Expressions -- Valvano.files/Image34.gif"
width=352></P>
<ADDRESS>Figure 5-6: Promotion can be used to avoid overflow and
underflow.</ADDRESS>
<ADDRESS> </ADDRESS>
<P>The other mechanism for handling addition and subtraction errors is called
ceiling and floor. It is analogous to movements inside a room. If we try to move
up (add a positive number or subtract a negative number) the ceiling will
prevent us from exceeding the bounds of the room. Similarly, if we try to move
down (subtract a positive number or add a negative number) the floor will
prevent us from going too low. For our 8 bit addition and subtraction, we will
prevent the 0 to 255 and 255 to 0 crossovers for unsigned operations and -128 to
+127 and +127 to -128 crossovers for signed operations. These operations are
described by the following flowcharts. If the carry bit is set after an unsigned
addition the result is adjusted to the largest possible unsigned number
(ceiling). If the carry bit is set after an unsigned subtraction, the result is
adjusted to the smallest possible unsigned number (floor.)</P>
<P><IMG height=163 src="Chapter 5 Expressions -- Valvano.files/Image35.gif"
width=287></P>
<ADDRESS>Figure 5-7: In assembly language we can detect overflow and
underflow.</ADDRESS>
<ADDRESS> </ADDRESS>
<P>If the overflow bit is set after a signed operation the result is adjusted to
the largest (ceiling) or smallest (floor) possible signed number depending on
whether it was a -128 to 127 cross over (N=0) or 127 to -128 cross over (N=1).
Notice that after a signed overflow, bit 7 of the result is always wrong because
there was a cross over.</P>
<P><IMG height=163 src="Chapter 5 Expressions -- Valvano.files/Image36.gif"
width=413></P>
<ADDRESS>Figure 5-8: In assembly language we can detect overflow and
underflow.</ADDRESS>
<P> </P>
<P><FONT face="Times New Roman,Times">Go to <A
href="http://www.ece.utexas.edu/~valvano/embed/chap6/chap6.htm">Chapter 6 on
Statements</A> Return to <A
href="http://www.ece.utexas.edu/~valvano/embed/toc1.htm">Table of
Contents</A></FONT></P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -