ARM64

ARM64

  • cpu架构
  • 一条arm指令占32bit

寄存器

  • 通用寄存器64bit下有 x0-x28 共29个, w0-w28 属于x0-x28的低32bit;x0-x7通常用来存放函数名和参数,更多参数放到堆栈;x0通常用来存放函数返回值
  • 程序计数器pc(program counter),记录cpu当前执行到哪一条指令,存放着当前cpu正在执行指令的地址,pc存谁就执行谁
  • 堆栈指针 做堆栈平衡用
    • sp(stack pointer), 也叫栈顶指针
    • fp(frame pointer),x29 也叫栈底指针
  • 链接寄存器lr(link register), x30, 存储着函数的返回的指令地址
  • 程序状态寄存器
    • cpsr(current program status register) 0x10000000,cpsr的低8位(包括I、F、T和M[4:0])称为控制位,程序无法修改,除非CPU运行于特权模式下,程序才能修改控制位! M有5位,控制CPU运行模式
      CPSR01.png
    • N【负数标志】、Z【0标志】、C【进位标志】、V【溢出标志】均为条件码标志位。
    • 高4位31-28,27-8保留位, 后8位7-0控制位
    • N:nagetive 正负标志,N=1表示运算结果为负,N=0表示运算结果为正或0, cmp x0, x1
    • Z:zero零标志, Z=1表示运算结果为0,Z=0表示运算结果为非0, cmp x0, x1
    • C carray
      • 进位标志,加法运算产生了进位时则C=1,否则C=0;
      • 借位标志,减法运算产生了借位则C=0,否则C=1;
    • V:overflow 溢出标志,V=1表示有溢出,V=0表示无溢出
    • Q:累计饱和instructions
    • T:说明执行的指令是ARM指令(0),还是Thumb指令(1)
    • F: 6,第7位 FIQ的缩写,是否禁用FIQ 为1的话表示不允许快速中断
    • I: disable IRQ
    • A: 8 是否disable异步abort
    • E: 9,endian 操作储存的字节顺序,0=;1=
      • 32位一个字长为4个字节
      • 进行存取时都是按字长进行存取。一小片一小片的进行存取,不进行分割,存储到地址里面,字节的顺序,
      • 低位存低地址,高位存高地址。小端
      • 低位存高地址,高位存低地址。大端
    • 10-15: 针对Thumb2指令
    • 16-19: SIMD(单指令,多数据)指令使用
    • 20-23: 保留
    • 24: 是否jzalle状态
    • 25-26: Thumb-2指令的if...then条件执行
      CPSR02.png
    • spsr(saved program status register),异常状态
register read [x0]
register write x0 0x11000000 00000022
register write w0[低32bit] 0x11000000 00000022

指令

  • ret 函数返回,将lr的值赋值给pc
  • mov {条件} 目的寄存器,源操作数[立即数#号开头]
  • add {条件} 目的寄存器, 操作数1,操作数2
  • sub {条件} 目的寄存器, 操作数1,操作数2
  • cmp {条件} 操作数1,操作数2
.text
.global _test

_test:
mov x0, #0x3
mov x1, #0x1
cmp x0, x1 ;x0 - x1的值 存入cpsr 0x00000000 非负非零
;sub x2, x0, x1 把x0-x1的值 放入x2
  • b[jump] {条件} 目标地址,经常和cmp结合使用
b tag ; 转汇编时 b 0x100088765
mov x0, #0x8 
tag:
mov x1, #0x6

; 条件跳转
beq tag ;equal
bne tag ;no equal
bgt tag ;great than
blt tag ;less than
bge tag ;great or equal
  • bl {条件} 目标地址,带返回的跳转=出函数栈,b指令子函数ret无效。l-link register, 先将下一条指令地址存到lr,再b一下
func:
mov x0, #0x1
mov x1, #0x2
add x2, x0, x1
ret

_test:
bl func
mov x3, #0x2
mov x4, #0x1
  • 指令条件域
    指令的条件域.png
  • 内存操作
    • load,从内存中读。ldr,ldur,ldp
    ; 间接寻址
    ldr x0, [内存地址]
    ldr x0, [x1] ; 从内存地址取8个word
    ldr w0, [0x1234] ;取4个字
    ; 基址变址寻址 `offset`偏移值
    ldur x0, [x1, #0x4];从x1+0x4的内存地址取8个w
    ldur x0, [x1, #0x4]!  ; x0=x1+4 x1=x1+4
    ldur x0, [R1], #4   ; x0<-[x1], x1=x1+4
    ;
    ldp(pair 一对) w0, w1 ,[x2, #0x30] ; 在x2+0x30的地址开始读 分 
    别读给w0 w1
    
    • store,向内存里写。str,stur,stp
    str w0, [x1] ;将w0的值 存到指定地址
    stp w0, w1 ,[x2, #0x30]
    
    • 零寄存器,wzr, xzr, 里面存储的是0。可以通过这两个寄存器快速
      清零内存

其它指令助记

  • MADD Rd, Rn, Rm, Ra => Rd = Ra + Rn*Rm
  • MSUB Rd, Rn, Rm, Ra => Rd = Ra - Rn*Rm