在ARMv7汇编中,代码片段:
1: b 1b //Done
作用是创建一个无限循环,使程序永远停留在当前位置,不在执行后续命令;
语法解释:
1::这是一个局部标签(local label)。在 ARM 汇编中,以数字开头的标签(如 1:)是局部标签,可以通过 b 1b 或 b 1f 引用。
1b:表示向后查找最近的 1: 标签(Backward)。
1f:表示向前查找最近的 1: 标签(Forward)。
b 1b:这是一个分支指令(Branch),跳转到最近的 1: 标签(向后查找)。由于标签 1: 就在当前行,这条指令会无限循环跳转到自身。
代码 1: b 1b 的作用是让程序在当前位置无限循环,防止后续未定义代码的执行。这是裸机编程或嵌入式系统中常见的“安全终止”方法。
具体在裸机程序(无操作系统)或嵌入式系统中,这种无限循环常用于:
ADD R0, R1, R2 @ R0 = R1 + R2
ADD R3, R4, #10 @ R3 = R4 + 10
SUB R0, R1, R2 @ R0 = R1 - R2
SUB R3, R4, #5 @ R3 = R4 - 5
LSL R0, R1, #4 @ R0 = R1 << 4
LSR R0, R1, #3 @ R0 = R1 >> 3(无符号)
ASR R0, R1, #2 @ R0 = R1 >> 2(保留符号)
ROR R0, R1, #8 @ R0 = R1 循环右移8位
MUL R0, R1, R2 @ R0 = (R1 × R2) 的低32位
MLA R0, R1, R2, R3 @ R0 = (R1 × R2) + R3
Write a function that returns the bitwise inversion of its parameter.
int invert (int n);
.global _start
_start:
mov r0, #1
bl invert
1: b 1b // Done
.global invert
invert:
MVN r0,r0 // MVN把R0里面的数取反然后再进行存储
BX lr //return caller
算法:最低位是0还是1,若是1则odd为1,若是为0,则odd为0;如何获得最低位呢,直接使用n & 1;
Steps:
.global _start
_start:
mov r0, #1
bl odd
1: b 1b // Done
.global odd
odd:
AND r0,r0,#1
BX lr
算法:进制补码中,负数的符号位是1,正数或零是0。所以,如果我能得到符号位的掩码,可能可以用异或和减法来计算绝对值。比如,对于n,如果符号位是0,那么绝对值是n本身;如果符号位是1,绝对值是~n + 1。或者用另一种方法:将n与符号位的掩码异或,然后减去掩码。这可能更高效。
步骤:
.global _start
_start:
mov r0, #10
bl abs
1: b 1b // Done
.global abs
abs:
ASR r1, r0, #31 // r1 = n>>31 to generate mask
EOR r0, r0, r1 // r0 = n ^ mask
SUB r0, r0, r1 // r0 = r0 - mask
BX lr
即第一个参数传递给R0,第二个参数传递给R1;
.global _start
_start:
mov r0, #1 // First function parameter is always passed through r0.
mov r1, #1 // Second function parameter is always passed through r1.
bl add // Return value is always in r0.
1: b 1b // Done
.global add
add:
ADD R0,R0,R1
BX LR
即将该参数移位到24位,低8位;
.global _start
_start:
ldr r0, =0x12345678
bl shift
b _start // End of testing code
// Convert one U32 sample to U8 format
shift:
LSR r0,r0,#24 //将输入参数 r0 右移24位,保留高8位到低8位
BX lr
// A test case to test your function with
.global _start
_start:
ldr r0, =0x40000
bl shift
b _start // End of testing code
// Return 1/4 amplitude for a S32 sample
shift:
ASR r0,r0,#2 //算数右移
BX lr
// A test case to test your function with
.global _start
_start:
ldr r0, =0x1234
bl shift
b _start // End of testing code
// Convert one S16 to S32 format
shift:
LSL R0,R0,#16 // left shift 16
BX lr
以上是ARMv7汇编语言的常见算术指令运算;