Part 12 – Linux ARM Assembly Control Instructions/Hail Conjecture
ARM assembly control is as follows:
- IF, ELSE and ENDIF
- WHILE and WEND
- MACRO and WEND
- MEXIT
32 sample
Complete 1 + 2 +… + 22.
.text. global main main: mov R1, #0 /* R1 ← 0 */ mov R2, #1 /* R2 ← 1 */ loop: CMP R2, #22 /* compare R2 and 22 */ BGT end /* branch if R2 > 22 to end */ add R1, R1, R2 /* R1 ← R1 + R2 */ add r2, R2, #1 /* R2 ← R2 + 1 */ b Loop end: mov r0, R1 /* R0 ← R1 */ bx LRCopy the code
as -g -o loop01.o loop01.s
gcc -o loop01 loop01.o
Echo $? The result is 253.
Change #22 to #100 to get 1+2+… + 100 = 5050.
But can’t pass $? To obtain the result, because Linux error code return is 8 bits, 5050 more than 8 bits.
The binary of 5050 is 1001110111010. The following eight bits are 10111010, which is 186. Return 186, but through GDB debugging can go to see r1 its real 5050.
64 sample
.arch armv8-a
.global _start
.text
_start:
mov x1, #0 /* r1 ← 0 */
mov x2, #1 /* r2 ← 1 */
loop:
cmp x2, #22 /* compare r2 and 22 */
bgt end /* branch if r2 > 22 to end */
add x1, x1, x2 /* r1 ← r1 + r2 */
add x2, x2, #1 /* r2 ← r2 + 1 */
b loop
end:
mov x0, x1 /* r0 ← r1 */
mov x8, 93
svc 0
Copy the code
as -g -o loop64.o loop64.s
ld -o loop64 loop64.o
The command output is as follows:
echo $?
253
32 Example hail conjecture
Collatz’s conjecture is that a positive integer x is multiplied by 3 and multiplied by 1 if it is odd, or multiplied by an even number of 2n after several times, eventually returning to 1.
No matter what number N is, it ends up at 1. To be precise, it is the 4-2-1 cycle that cannot escape from the bottom.
.text. global main main: mov R1, #123 /* R1 ← 123 */ mov R2, #0 /* R2 ← 0 */ loop: CMP r1, #1 /* compare r1 and 1 */ beq end /* branch to end if R1 == 1 */ #0 /* compare r3 and 0 */ bne odd /* branch to odd if r3 ! = 0 */ even: mov R1, r1, ASR #1 /* R1 ← (R1 >> 1) */ b end_loop odd: Add R1, R1, R1, LSL #1 /* R1 ← R1 + (R1 << 1) */ add R1, R1, #1 /* R1 ← R1 + 1 */ end_loop: Add R2, R2, #1 /* R2 ← R2 + 1 */ b loop /* branch to loop */ end: mov r0, R2 bx lrCopy the code
as -g -o collatz.o collatz.s
gcc -o collatz collatz.o
The command output is as follows:
./collatz
echo $?
46
That’s 46 changes.
The entry parameter is 123, and the steps are as follows:
[123, 370, 185, 556, 278, 139, 418, 209, 628, 314, 157, 472, 236, 118, 59, 178, 89, 268, 134, 67, 202, 101, 304, 152, 76, 38, 19, 58, 29, 88, 44, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]
C code
#include <stdio.h> #include <stdint.h> int main () { unsigned long long i,n,x = 0; Int count = 0; int max = 0; n = 123; i = n; while(i! If (I %2 == 1) {if(I %2 == 1) {if(I %2 == 1); } else if(I %2 == 0) {I = I /2; } count++; Printf (" current: %llu[%d]\n",n, count); return 0; }Copy the code
gcc -o collatz-c collatz.c
That’s 46 changes.
64-bit example hail conjecture
.arch armv8-a. Global _start. text _start: mov x1, #123 /* R1 ← 123 */ mov x2, #0 /* R2 ← 0 */ loop: CMP x1, # compare r1 and 1 * 1 / * / / * branch beq end to end the if r1 = = 1 * / and x3, x1, # 1 / * 1 * / CMP x3 please r1 and r3, #0 /* compare r3 and 0 */ bne odd /* branch to odd if r3 ! = 0 */ even: mov x1, x1, ASR #1 /* R1 ← (r1 >> 1) */ b end_loop odd: Add x1, x1, x1, LSL #1 /* R1 ← R1 + (r1 << 1) */ add x1, x1, #1 /* R1 ← R1 + 1 */ end_loop: Add x2, x2, #1 /* R2 ← R2 + 1 */ b loop /* branch to loop */ end: mov x0,x2 mov x8, 93 SVC 0Copy the code
as -g -o collatz64.o collatz64.s
ld -o collatz64 collatz64.o
The result is as follows:
echo $?
46
From here we can see how simple it is to switch from 32-bit ARM assembly to 64-bit. Note the register changes and how you exit.