流控制-ARM汇编指令(三)
汇编指令中有分⽀跳转指令和条件执⾏指令,但是没有类似于C/C++中给出的流控制指令。实际在代码开发过程中,复杂的流控制过程都是通过跳转和条件实⾏来实现的。
1. 分⽀和条件执⾏
1.1. 分⽀指令
b{条件} <;地址>直接跳转到某个地址位置,这个地址位置⼀般是通过标签的⽅式来定义。
bl{条件} <;地址> 跳转到某个地址执⾏程序,过程中会⾃动将R15寄存器中的内容保存在R14寄存器中。
1.2. 条件执⾏
条件执⾏是汇编特有的属性,可以在分⽀跳转指令后链接条件执⾏命令,实现相关命令条件的跳转。这种⽅式相⽐较其他汇编指令使⽤jmp 这些指令灵活性会⼤很多。
EQ : 等于。如果⼀次⽐较之后设置了 Z 标志。
NE : 不等于。如果⼀次⽐较之后清除了 Z 标志。
VS : 溢出设置。如果在⼀次算术操作之后设置了 V 标志,计算的结果不适合放⼊⼀个 32bit ⽬标寄存器中。
汇编语言跳转指令
VC : 溢出清除。如果清除了 V 标志,与 VS 相反。
HI : ⾼于(⽆符号)。如果⼀次⽐较之后设置了 C 标志并清除了 Z 标志。
LS : 低于或同于(⽆符号)。如果⼀次⽐较操作之后清除了 C 标志或设置了 Z 标志。
PL : 正号。如果⼀次算术操作之后清除了 N。出于定义‘正号’的⽬的,零是正数的原因是它不是负数...
MI : 负号。如果⼀次算术操作之后设置了 N 标志。
CS : 进位设置。如果⼀次算术操作或移位操作之后设置了 C 标志,操作的结果不能表⽰为 32bit。你可以把 C 标志当作结果的第 33 位。CC : 进位清除。与 CS 相反。
GE : ⼤于或等于(有符号)。如果⼀次⽐较之后...设置了 N 标志并设置了 V 标志。或者...清除了 N 标志并清除了 V 标志。
GT : ⼤于(有符号)。如果⼀次⽐较之后...设置了 N 标志并设置了 V 标志。或者...清除了 N 标志并清除了 V 标志,并且...清除了 Z 标志。
LE : ⼩于或等于(有符号)。如果⼀次⽐较之后...设置了 N 标志并清除了 V 标志。或者...清除了 N 标志并设置了 V 标志,并且...设置了 Z 标志。
LT : ⼩于(有符号)。如果⼀次⽐较之后...,设置了 N 标志并清除了 V 标志。或者...清除了 N 标志并设置了 V 标志。
AL : 总是。缺省条件,所以不⽤明显声明。
NV : 从不。不是特别有⽤,它表⽰应当永远不执⾏这个指令。是穷⼈的 NOP。包含 NV 是为了完整性(与 AL 相对),你不应该在你的代码中使⽤它。
条件循环if在汇编中是不存在的,其只有通过CMP,配合jmpeq等这种跳转判断指令。
2. 流控制
可以通过命令组合的形式实现if/while/for流控制内容,具体通过实际的C代码和对应的汇编代码⽐较查看实现过程。中Loop是实现流控制的基础⽅法,通过不同的loop组合可以完成。
2.1. if条件
1写⼀个简单的
2
3C语⾔写法为:
4
5int a=10;
6
7int b=11;
8
9if(a>b)
10
11  a++;
12
13else
14
15b++;
16
17 AMR 汇编写法为
18
19
20mov ro,#0xa
21
22mov r1,#0xb
23
24cmp r0,r1 //影响了Z位
25
26addht r0,#1  如果a>b a++
27
28addls r1,#1 //else b++
29
30
31C代码
32
33if(a!=10&&b!=20)
34
35a=a+b;
36
37
38转回汇编
39
40mov r0,#3
41
42mov r1,#1
43
44cmp r0,#10
45
46cmpne r1,#20
47
48 addne r0,r0,r1
在ARM汇编语⾔中循环通过loop指令来实现,再复杂的while和for循环也是基于loop循环来实现。
2.2. for
1int GetSum(int val) //使⽤汇编求1+2+3+...+val的值
2{
3int sum = 0;
4__asm__ __volatile__(
5"MOV R5 , %1\n"//val放⼊寄存器r5
6"MOV R1 , #0\n" //sum = 0
7"MOV R2 , #1\n"//i = 1
8"LOOP:\n"
9" ADD R1 , R1 ,R2\n" //sum = sum + i
10" ADD R2 , R2 ,#1\n" //i++
11" CMP R5 , R2\n" //判断 i 是否等于val if(i==val)
12" BEQ END\n" //若相等跳转⾄END处 break
13" B LOOP\n" //若不相等跳转⾄LOOP处进⼊下次循环 else continue
14"END:\n"
15"MOV %0 , R1\n" //sum = R1
16:"=r"(sum)//输出
17:"r"(val)//输⼊
18:"memory"
19);
20return sum;
21}
22随便写了个求和的例⼦其余的循环⼤同⼩异不懂可以继续探讨运⾏之前请交叉编译然后在ARM平台上运⾏2.3. while
1.section .data
2.output:
3    .ascii "%d\n\000"
4.section .text
5    .global main
6main:
7    mov ip, sp
8    stmfd sp!, {fp,ip,lr,pc}
9    sub fp, ip, #4
10    sub sp, sp, #80
11
12    @memory and register 13
14    mov r3, # 1
15    mov r0,r3
16
17loop:
18    cmp r0,# 15
19    bge stop
20    mov r1,# 1
21    add r2, r0, r1
22    mov r0, r2
23
24    @保护现场
25    str r0, [fp,#-16]
26
27    str r0,[fp,# -20 ]
28    ldr r0, =.output
29    ldr r1,[fp,# -20 ]
30    bl printf
31
32    @恢复现场
33    ldr r0,[fp,#-16]
34
35      b loop
36stop:
37    ldmea fp, {fp,sp,pc}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。