## Section12.3Binary Decisions

We now know how to implement two of the primary program flow constructs—sequence and repetition. We continue on with the third—binary decision. You know this construct from high-level languages as the if or if-else statement.

### Subsection12.3.1Simple if-else

We start the discussion with a common example—a simple program that asks the user whether changes should be saved or not (Listing 12.3.1). This example program does not do anything, so there really is nothing to change, but you have certainly seen this construct. (As usual, this program is meant to illustrate concepts, not good C/C++ programming practices.)

Let's look at the flow of the program that the if-else controls:

1. The Boolean expression (response == 'y') is evaluated.

2. If the evaluation is true, the first block, the one that displays “Changes saved.”, is executed.

3. If the evaluation is false, the second block, the one that displays “Changes discarded.”, is executed.

4. In both cases the next statement to be executed is return 0;.

The way that the if-else construct controls program flow can be seen from the flow chart in Figure 12.3.2.

This flow chart shows that we need the following assembly language tools to construct an if-else:

• Instruction(s) to evaluate Boolean expressions.

• An instruction that conditionally transfers control (branches) to another location in the program. This is represented by the large diamond, which shows two possible paths.

• An instruction that unconditionally transfers control to another location in the program. This is represented by the line that leads from “Execute ‘Then’ part” to the end of the if-else construct. Program control must branch around the “Else” part.

We already know the instructions that are needed to implement an if-else construct. The important thing to note is that there must be an unconditional branch at the end of the “then” block to transfer program flow around the “else” block. The assembly language generated for this program is shown in Listing 12.3.3.

This program introduces a new instruction, ldrb, which as you probably guess, loads a byte from memory. We also introduce the strb instruction for completness.

LDRB

Loads a byte from memory into a register and zeroes the 24 high-order bits.

LDRB<c>  <Rt>, <label>                     % Label
LDRB<c>  <Rt>, [<Rn>{, #+/-<imm>}]         % Offset, immediate
LDRB<c>  <Rt>, [<Rn>, #+/-<imm>]!          % Pre-indexed, immediate
LDRB<c>  <Rt>, [<Rn>], #+/-<imm>           % Post-indexed, immediate
LDRB<c>  <Rt>, [<Rn>, +/-<Rm>{, <shift>}]  % Offset, register
LDRB<c>  <Rt>, [<Rn>, +/-<Rm>{, <shift>}]! % Pre-indexed, register
LDRB<c>  <Rt>, [<Rn>], +/-<Rm>{, <shift>}  % Post-indexed, register

• <c> is the condition code, Table 9.2.1.

• <Rt> is the destination register, <Rn> is the base register, and <Rm> contains an offset value.

• <label> is a labeled memory address.

• <imm> is a signed integer in the range $$-2048 \ldots +2047\text{.}$$

The memory address to load the word from is determined the following way (further explained in Section 11.1):

• The Label form uses the address corresponding to the <label>.

• In the Offset form, the signed integer is added to the value in the base register, <Rn>, the value at this address is loaded into <Rt>, but the base register is not changed.

• In the Pre-indexed form, the signed integer is added to the value in the base register, <Rn>, the base register is updated to the new address, and then the value at this new address is loaded into <Rt>.

• In the Post-indexed form, the signed integer is added to the value in the base register, <Rn>, the value at this new address is loaded into <Rt>, and then the base register is updated to the new address.

STRB

Stores a word from a register into memory.

STRB<c>  <Rt>, <label>                     % Label
STRB<c>  <Rt>, [<Rn>{, #+/-<imm>}]         % Offset, immediate
STRB<c>  <Rt>, [<Rn>, #+/-<imm>]!          % Pre-indexed, immediate
STRB<c>  <Rt>, [<Rn>], #+/-<imm>           % Post-indexed, immediate
STRB<c>  <Rt>, [<Rn>, +/-<Rm>{, <shift>}]  % Offset, register
STRB<c>  <Rt>, [<Rn>, +/-<Rm>{, <shift>}]! % Pre-indexed, register
STRB<c>  <Rt>, [<Rn>], +/-<Rm>{, <shift>}  % Post-indexed, register

• <c> is the condition code, Table 9.2.1.

• <Rt> is the source register, and <Rn> is the base register.

• <label> is a labeled memory address.

• <imm> is a signed integer in the range $$-2048 \ldots +2047\text{.}$$

The memory address to store the word at is determined the following way (further explained in Section 11.1):

• The Label form uses the address corresponding to the <label>.

• In the Offset form, the signed integer is added to the value in the base register, <Rn>, the value in <Rt> is stored at this address, but the base register is not changed..

• In the Pre-indexed form, the signed integer is added to the value in the base register, <Rn>, the base register is updated to the new address, and then the value in <Rt> is stored at this address.

• In the Post-indexed form, the signed integer is added to the value in the base register, <Rn>, the value in <Rt> is stored at this address, and then the base register is updated to the new address.

Our assembly language version of the yes/no program in Listing 12.3.4 follows this general pattern. It, of course, uses more meaningful labels than what the compiler generated.

The branch out of the “then” block over the “then” block:

yesLoop:
ldrb    r3, [r4]        @ get a char
cmp     r3, NUL         @ end of string?
beq     endThen         @ yes, end of then block
mov     r0, STDOUT      @ no, write to screen
mov     r1, r4          @ address of current char
mov     r2, 1           @ write 1 byte
bl      write
add     r4, r4, 1       @ increment pointer var
endThen:
b       endElse         @ branch over else block


could be done more efficiently with:

yesLoop:
ldrb    r3, [r4]        @ get a char
cmp     r3, NUL         @ end of string?
beq     endElse         @ yes, end of if-else construct
mov     r0, STDOUT      @ no, write to screen
mov     r1, r4          @ address of current char
mov     r2, 1           @ write 1 byte
bl      write
add     r4, r4, 1       @ increment pointer var


But it would be very rare for this gain in efficiency to be noticeable. On the other hand, using the strict “if-then-else” structure makes the code more readable for anyone who modifies it. The trade-off here is an almost certainly unnoticeable performance gain versus a fair chance of introducing a bug into the code. (In case you have not learned this yet, it is much easier to make a coding error in code that is more difficult to read.)

The overall structure of an if-else can be seen in Listing 12.3.5 follows this general pattern. It, of course, uses more meaningful labels than what the compiler generated.

### Subsection12.3.2Range Checking

Another common programming problem is to check to see if a variable is within a certain range. This requires a compound Boolean expression, as shown in the C program in Listing 12.3.6.

We will move directly to my assembly language version of this range-checking program in Listing 12.3.7.

When a Boolean expression is used to control the flow of a program (for example, while loop, if-else) most language employ Short Circuit Evaluation of the expression. That is, as each term is evaluated, if it is determined that the entire expression evaluates to either “true” or “false” the appropriate action is taken, without evaluating the remaining terms in the expression. We can see how this is implemented by looking at the assembly language that implements the Boolean expression,

((response <= '9') && (response >= '0'))


From Listing 12.3.7 this is the code sequence:

ldrb    r3, [fp, #-response] @ load response
cmp     r3, #'9         @ check high end
bhi     notNumeral      @ >'9', other char
cmp     r3, #'0         @ check low end
blo     notNumeral      @ <'0', other char


If it is determined that the user's response is higher than the character ‘9’, there is no need to do further checking. The bhi notNumeral instruction “short circuits” further evaluation of this Boolean expression.