Section 14.1 Logical Instructions
Two numeric operators, addition and subtraction, were introduced in Section 9.2. Many data items are better thought of as bit patterns rather than numerical entities. For example, study Table 2.13.1 and see if you can determine which bit determines the case (upper/lower) of the alphabetic characters.
In order to manipulate individual character codes in a text string, we introduce the bit-wise logical instructions in this section. The bitwise logical operations were shown in the truth tables in Table 4.4.2–Table 4.4.4. The instructions available to us to perform the three binary operations are:
AND
-
Performs a bitwise AND between two integers.
AND{S}{<c>} {<Rd>,} <Rn>, #<const> % immediate AND{S}{<c>} {<Rd>,} <Rn>, <Rm>{, <shift>} % register AND{S}{<c>} {<Rd>,} <Rn>, <Rm>, <type> <Rs> % register-shifted register
If ‘
S
’ is present the condition flags are updated according to the result. If absent, the condition flags are not changed.<c>
is the condition code, Table 9.2.1.<Rd>
specifies the destination register, and<Rm>
and<Rn>
are the source registers.<Rs>
contains the shift amount in the “register-shifted register” form.\(-257 \le const \le +256\text{,}\) or \(const = +256, +260, +264, \ldots, +65280\text{,}\) or \(const = -261, -265, \ldots, -65281\text{.}\) This odd sequence of values will be explained in Section 11.3.3
<shift>
and<type>
are explained in Section 9.2.3
In the “immediate” form, a bitwise AND is performed between
<const>
and the value in<Rn>
. In the “register” and “register-shifted register” forms, a bitwise AND is performed between the value in<Rm>
and the value in<Rn>
. If a shift is specified, the value in<Rm>
is shifted by the specified amount before the AND is performed. If<Rd>
is present the result is stored there and<Rn>
is unchanged. If not, the result is stored in<Rn>
. The values in<Rm>
and<Rs>
are unchanged. ORR
-
Performs a bitwise inclusive OR between two integers.
ORR{S}{<c>} {<Rd>,} <Rn>, #<const> % immediate ORR{S}{<c>} {<Rd>,} <Rn>, <Rm>{, <shift>} % register ORR{S}{<c>} {<Rd>,} <Rn, <Rm>, <type> <Rs> % register-shifted register
If ‘
S
’ is present the condition flags are updated according to the result. If absent, the condition flags are not changed.<c>
is the condition code, Table 9.2.1.<Rd>
specifies the destination register, and<Rm>
and<Rn>
are the source registers.<Rs>
contains the shift amount in the “register-shifted register” form.\(-257 \le const \le +256\text{,}\) or \(const = +256, +260, +264, \ldots, +65280\text{,}\) or \(const = -261, -265, \ldots, -65281\text{.}\) This odd sequence of values will be explained in Section 11.3.3
<shift>
and<type>
are explained in Section 9.2.3
In the “immediate” form, a bitwise inclusive OR is performed between
<const>
and the value in<Rn>
. In the “register” and “register-shifted register” forms, a bitwise inclusive OR is performed between the value in<Rm>
and the value in<Rn>
. If a shift is specified, the value in<Rm>
is shifted by the specified amount before the inclusive OR is performed. If<Rd>
is present the result is stored there and<Rn>
is unchanged. If not, the result is stored in<Rn>
. The values in<Rm>
and<Rs>
are unchanged. EOR
-
Performs a bitwise exclusive EOR between two integers.
EOR{S}{<c>} {<Rd>,} <Rn>, #<const> % immediate EOR{S}{<c>} {<Rd>,} <Rn>, <Rm>{, <shift>} % register EOR{S}{<c>} {<Rd>,} <Rn, <Rm>, <type> <Rs> % register-shifted register
If ‘
S
’ is present the condition flags are updated according to the result. If absent, the condition flags are not changed.<c>
is the condition code, Table 9.2.1.<Rd>
specifies the destination register, and<Rm>
and<Rn>
are the source registers.<Rs>
contains the shift amount in the “register-shifted register” form.\(-257 \le const \le +256\text{,}\) or \(const = +256, +260, +264, \ldots, +65280\text{,}\) or \(const = -261, -265, \ldots, -65281\text{.}\) This odd sequence of values will be explained in Section 11.3.3
<shift>
and<type>
are explained in Section 9.2.3
In the “immediate” form, a bitwise exclusive OR is performed between
<const>
and the value in<Rn>
. In the “register” and “register-shifted register” forms, a bitwise exclusive OR is performed between the value in<Rm>
and the value in<Rn>
. If a shift is specified, the value in<Rm>
is shifted by the specified amount before the exclusive OR is performed. If<Rd>
is present the result is stored there and<Rn>
is unchanged. If not, the result is stored in<Rn>
. The values in<Rm>
and<Rs>
are unchanged.
The bitwise NOT instruction, mvn, and the bitwise compare instruction, tst, have already been given.
Listings 14.1.1–14.1.2 show how the and
instruction can be used to convert lowercase characters to uppercase when some of the characters may already be uppercase. The algorithms of both the main
and toUpper
functions are very similar to those of main
and writeStr
in Exercise 13.3.4 and Exercise 13.3.2, respectively, so I go directly to assembly language rather than show the C solution first.
@ upperCase.s @ Prompts user to enter alphabetic characters, converts @ all lowercase to uppercase and shows the result. @ 2017-09-29: Bob Plantz @ Define my Raspberry Pi .cpu cortex-a53 .fpu neon-fp-armv8 .syntax unified @ modern syntax @ Constant for assembler .equ nBytes,50 @ amount of memory for string @ Constant program data .section .rodata .align 2 prompt: .asciz "Enter some alphabetic characters: " @ The program .text .align 2 .global main .type main, %function main: sub sp, sp, 8 @ space for fp, lr str fp, [sp, 0] @ save fp str lr, [sp, 4] @ and lr add fp, sp, 4 @ set our frame pointer mov r0, nBytes @ get memory from heap bl malloc mov r4, r0 @ pointer to new memory ldr r0, promptAddr @ prompt user bl writeStr mov r0, r4 @ get user input mov r1, nBytes @ limit input size bl readLn mov r0, r4 @ convert to uppercase bl toUpper mov r0, r4 @ echo user input bl writeStr mov r0, r4 @ free heap memory bl free mov r0, 0 @ return 0; ldr fp, [sp, 0] @ restore caller fp ldr lr, [sp, 4] @ lr add sp, sp, 8 @ and sp bx lr @ return promptAddr: .word prompt
toUpper
function in Listing 14.1.2. (prog asm)@ toUpper.s @ Converts all alpha characters to uppercase. @ Calling sequence: @ r0 <- address of string to be written @ bl toUpper @ returns number of characters written @ 2017-09-29: Bob Plantz @ Define my Raspberry Pi .cpu cortex-a53 .fpu neon-fp-armv8 .syntax unified @ modern syntax @ Useful source code constants .equ upperMask,0x5f .equ NUL,0 @ The code .text .align 2 .global toUpper .type toUpper, %function toUpper: sub sp, sp, 16 @ space for saving regs str r4, [sp, 0] @ save r4 str r5, [sp, 4] @ r5 str fp, [sp, 8] @ fp str lr, [sp, 12] @ lr add fp, sp, 12 @ set our frame pointer mov r4, r0 @ r4 = string pointer mov r5, 0 @ r5 = count whileLoop: ldrb r3, [r4] @ get a char cmp r3, NUL @ end of string? beq allDone @ yes, all done and r3, r3, upperMask @ convert to uppercase strb r3, [r4] @ update string add r4, r4, 1 @ increment pointer var add r5, r5, 1 @ count++ b whileLoop @ back to top allDone: mov r0, r5 @ return count; ldr r4, [sp, 0] @ restore r4 ldr r5, [sp, 4] @ r5 ldr fp, [sp, 8] @ fp ldr lr, [sp, 12] @ lr add sp, sp, 16 @ restore sp bx lr @ return