b.ne label //不等时跳转
cbz w10, 1f //w10值等于0的适合,跳转导1f
ret //子程序返回指令,返回地址默认保存在LR(X30),代替了mov pc,lr
ldr x0,=__main //大范围的地址读取:把标号__main(地址)读入x0
adr x0,vector //小范围的地址读取:把标号vector(地址)读入x0,标号距当前指令PC的偏移小于1M
stp x29, x30, [sp, #-16]!
//入栈:把x29, x30 存储到sp-16指向的空间后,sp自减16 (因寄存器是8字节,栈是向下生长故是 -16)
//类似前索引: *(sp-16) = x29,x30 sp=sp-16 (!使得sp能自更新) 把 x29,x30看成整体
//stp只支持2个寄存器,代替了复杂的stmfd (64位汇编,取消了批量操作指令)
ldp x29, x30, [sp],#16 //出栈: 把sp指向的空间内容载入到x29, x30后,sp加16
//类似后索引: x29,x30=*sp sp=sp+16
mrs x0, sctlr_el1 //读sctlr_el1内容到x0 (注:系统寄存器,都通过mrs msr来操作)
msr sctlr_el1, x0 //写x0内容到 sctlr_el1
svc #2 //系统调用指令(触发一个同步异常,cpu则会陷入EL1)
.global _start //声明_start 为全局符号(让链接脚本能看到)
.quad 0x3FA0 //在存储器中分配8个字节,初值设为0x3FA0
.align 4 //2^4 =16 字节对齐
.macro myAdd, x,y //宏函数, 类似 myAdd(x, y)
add \x,\x,\y
.endm
myAdd x0,x2
b.ne lable //不等时跳转到标号
cbz w10, 1f //w10值等于0的适合,跳转导1f
ret //子程序返回指令,返回地址默认保存在LR(X30),代替了mov pc,lr
延时函数
.globl _start
_start:
mov x0,#3
bl delay
reset_end:
b reset_end
delay:
ldr x4,=0x03
loop_delay:
sub x4,x4,#1
cmp x4,#0
cbz x4,delay_end
b.ne loop_delay
delay_end:
ret
.macro myAdd, x,y //宏函数, 类似 myAdd(x, y)
add \x,\x,\y
.endm
myAdd x0,x2
宏函数跳转标号
.macro switch_el, xreg, el1_label
mrs \xreg, CurrentEL
cmp \xreg, 0x4
b.eq \el1_label
.endm
.globl _start
_start:
mov x0, #0x4
switch_el x0, 1f
mov x2,#2
reset_end:
b reset_end
1:
mov x2,#0x30
b reset_end