Unconditional Branch
The simplest branch instruction is
B label 无条件分支跳转
有符号数为负则设置N标志,否则clear
结果为0 设置此标志,否则clear
加法中溢出了则设置此标志,减法不需要借也就是结果不为负则设置,移位中保存最后一位移出的值;
加法或减法中 ,有符号数溢出则设置此标志位
这些标志位存在一个NZCV系统寄存器中,只允许特权访问
只有在指令的后追加S才会设置标志位,除了“比较”命令
B.{condition} label 按条件分支
CMP Xn, Operand2 比较,等同于 SUBS XZR, Xn, Operand2;cmp命令自动set flag;
按位与 异或 或 按位清零
bic 清零xs的位 ,由操作数2中位为1的位指定
48 = 0
65 = A
97 = a
单个ascii字符 char 用单引号''括起来,多个字符的字符串用"" 双引号括起来
下面是一个程序打印寄存器里的hex值,
// // a program to print a register in hex // .global _start _start: ldr x0,=hexbase ldr x1,=hexstr mov x2,0xabcd movk x2,0x1234,lsl 16 movk x2,0x5678,lsl 32 movk x2,0x09ef,lsl 48 add x1,x1,17 //point to the last char loop: and x3,x2,0xf //get 4 bits ldrb w4,[x0,x3] //get the char from hexbase strb w4,[x1] //write to hexstr sub x1,x1,1 //prepare next write lsr x2,x2,4 //x2 shit right 4bits to prepare next loop cmp x2,0 b.eq cout //break loop if x2=0 b loop cout: mov x0,1 //stdout ldr x1,=hexstr //str to print mov x2,19 // count to print mov x8,64 // linux write system call svc 0 mov x0,0 mov x8,93 //return 0 svc 0 .data hexbase: .ascii "0123456789abcdef\n" hexstr: .ascii "0x0000000000000000\n"
hexbase是16进制字符表,hexstr保存hex字符串
这个程序我自己写的,跟书上的不一样,我好nb!
3级流水机制,实现每一个时钟周期一条指令,跳转会用3个时钟周期,现代armCPU的分支预测机制跟降低跳转的延迟,程序应该少用跳转,不仅效率的考虑,分支太多让程序难以理解。