Program 7.4 contains four separate signed if-then structures, where G is signed 32 bits. In each case, the first step is to bring the first value in R0; the second step is to compare the first value with a second
Similar to Program 7.2, Program 7.4 will call GGreater7 if G is greater than 7, GGreaterEq7 if G is greater than or equal to 7, GLess7 if G is less than 7, and GLessEq7 if G is less than or equal to 7.
When comparing signed values, the instructions BGT BLT BGE and BLE should follow the subtraction or comparison instruction. A conditional if-then is implemented by bringing the first number in a register, subtracting the second number, then using the branch instruction with complementary logic to skip over the body of the if-then. To convert these examples to 16 bits, use the LDRSH R0,[R2]
instruction instead of the LDR R0,[R2] instruction. To convert these examples to 8 bits, use the LDRSB R0,[R2] instruction instead of the LDR R0,[R2] instruction.
Checkpoint 7.7: Assume you have a 32-bit signed global variable N. Write C code that executes the function isNeg, if N is negative.
Common error: It is an error to use an unsigned conditional branch when comparing two signed values.
Similarly, it is a mistake to use a signed conditional branch when comparing two unsigned values.
Observation: One cannot directly compare a signed number to an unsigned number. The proper method is to first convert both numbers to signed numbers of a higher precision and then compare.
Example 7.2. Redesign the Example 7.1 code assuming G1 is 8-bit signed. In particular we restrict the range to -128 to +50.
Solution: We can use the same flowchart shown previously in Figure 7.3. The way to compare two values is to subtract them from each other and check if that subtraction resulted in a positive number, zero, or negative number. If the subtraction yields a zero, then the numbers are obviously equal and the Z bit will be set. If it is positive, that means the first value is bigger than the second value and the N bit will be 0. If it is negative, then the first value is smaller than the second one and the N bit will be 1. In this case we bring G1 into Register R0 this time using LDRSB to load a signed byte (first value), and subtract 50 (second value). The CMP instruction subtracts 50 from R0 but doesn't save the result, it just sets the condition codes. The BLE uses the condition codes to branch to next if G1 is less than or equal to 50, as presented in Program 7.5. However, we will use a signed conditional branch (BLE) because the data format is signed..
Program 7.5. A signed if-then structure LDRSB is a signed 8-bit load. BLE is a signed branch.
Notice that the C code for Program 7.2 looks similar to Program 7.4, and the C code for Program 7.3 looks similar to Program 7.5. This is because the compiler knows the type of variables G1 and G2;
therefore, it knows whether to utilize unsigned or signed branches. Unfortunately, this similarity can be deceiving. When writing code whether it be assembly or C, you still need to keep track of whether your variables are signed or unsigned. Furthermore, when comparing two objects, they must have comparable types. E.g., “Which is bigger, 2 unsigned apples or –3 signed dollars?” The compiler does not seem to reject comparisons between signed and unsigned variables as an error. However, I recommend that you do not compare a signed variable to an unsigned variable. When comparing objects of different types, it is best to first convert both objects to the same format, and then perform the comparison. Conversely, we see that all numbers are converted to 32 bits before they are compared. This means there is no difficulty comparing variables of differing precisions: e.g., 8-bit, 16-bit, and 32-bit as long as both are signed or both are unsigned.
We can use the unconditional branch to add an else clause to any of the previous if then structures.
A simple example of an unsigned conditional is illustrated in the Figure 7.4 and presented in Program 7.6. The first three lines test the condition G1>G2. If G1>G2, the software branches to high. Once at high, the software calls the isGreater subroutine then continues. Conversely, if G1≤G2, the software does not branch and the isLessEq subroutine is executed. After executing the isLessEq subroutine, there is an unconditional branch, so that only one and not both subroutines are called.
Figure 7.4. Flowchart of an if-then-else structure.
Program 7.6. An unsigned if-then-else structure (unsigned 32-bit).
The selection operator takes three input parameters and yields one output result. The format is Expr1 ? Expr2 : Expr3
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 promotion is applied. The left and right side perform identical
A 3-wide median filter can be designed using if-else conditional statements.
short Median(short u1,short u2,short u3){ short result;
if(u3>u2) result=u2; // u2>u1,u3>u2 u3>u2>u1
else
if(u1>u3) result=u1; // u2>u1,u2>u3,u1>u3 u2>u1>u3 else result=u3; // u2>u1,u2>u3,u3>u1 u2>u3>u1 return(result);
}
Program 7.7. A 3-wide median function.
Checkpoint 7.8: Assume you have a 32-bit unsigned global variable N. Write C code that changes N to