ARM64 汇编 - 文章教程

ARM64 汇编

发布于 2021-03-20 字数 4495 浏览 1112 评论 0

iOS 汇编

  • 真机:ARM64 汇编
    • 寄存器
    • 指令
    • 堆栈
  • 模拟器:x86 汇编

寄存器

  • 通用寄存器
    • 64bit的:x0~x63
    • 32bit的:w0w31(属于x0x31的低32bit)
      • register:寄存器的意思
      • register read x0:读
      • register write x0 0x1000000000000001:写
      • register read :看所有的寄存器
    • x0 ~ x7 通常拿来存放函数的参数,更多的参数使用堆栈来传递
    • x0通常拿来存放函数的返回值
  • 程序计数器
    • pc (Program Counter)
    • 记录 CPU 当前指令的那一条指令
    • 存储着当前CPU正在执行的指令的指令
    • 类似以8086汇编的ip寄存器
  • 堆栈指针
    • sp(Stack Pointer),栈顶指针
    • fp(Frame Pointer),函数调用栈的栈底指针
  • 链接寄存器
    • lr(Link Register),也就是x30
    • 存储着函数的返回地址,bl指令在跳转前,将下一步要执行的指令地址放在lr中
  • 程序状态寄存器
    • cpsr(Current Program Status Register)
    • spsr(Saved Programe Status Register),异常状态下使用

汇编代码

在 OC 或 C 语言代码中直接插入汇编代码

__asm({ 

})

建立 .s 汇编文件(.asm 的简写)

arm.h 文件

void test(); ///函数的声明,方便外部调用


arm.s 文件

.text ;告诉编译器代码放哪儿
.global _test, _add;函数的实现默认是私有的,加这个表示是公开的
///函数名称实现
_test: ;c语言函数编译后,函数名前会自动加_, C语言函数名与汇编中加下划线的标记对应
mov x0 #0x8 ;将8存入x0寄存器中
; /// 汇编中的注释

mov x0, #0x1 
mov x1, #0x2 
add x2, x0, x1 ;将x0和x1相加赋值给x2

mov x0, #0x5 
mov x1, #0x2 
sub x2, x0, x1 ;将x0减x1赋值给x2

mov x0, #0x5 
mov x1, #0x2 
cmp x0, x1 ;x0减x1,减去的结果放cpsr寄存器

b mycode
mov x0, #0x5
mycode:
mov x1, #0x2

mov x0, #0x5 
mov x1, #0x2 
cmp x0, x1
beq mycode
mov x0, #0x5
ret ;不返回会一直往下执行
mycode:
mov x1, #0x2


ldr x0 [x1];把寄存器x1中内存地址的中存放的数据复制到寄存器x0
ldr x0 [x1, #0x6]; 寄存器x1中内存地址偏移0x6

ldr w0, w1 [x2, #0x10]; 从x2+0x20 取相应字节的内存数据到w0寄存器,再顺序取后面的到w1寄存器

str x0 [x1]; 把寄存器x0的数据写入到寄存器x1中内存地址,x0不能用立即数替代,因为立即数没有字节长度
stp x29, x30, [sp, #-16]!; // 把 x29, x30的值存到 sp-16的地址上,并且把 sp-=16.
str x5, [sp, #24]; // 把x5的值(64位数值)存到 sp+24 指向的内存地址上

ret ;返回,没有返回,会一直执行,直到ret

#0x2 这样的直接明确的数字就是立即数

指令

  • ret
    • 函数返回
  • mov
    • mov 目的寄存器, 源操作数
  • add
  • sub
  • cmp
    • 将2个寄存器相减
    • 相减的结果回影响cpsr寄存器的标志位
  • b
    • 跳转指令
    • 可以带条件跳转,一般跟cmp配合使用
  • bl
    • 带返回的跳转指令(函数调用)
    • 执行的操作
      • 将下一条指令的地址存储到**lr(x30)**寄存器中
      • 跳转到标记处开始执行
      • 标记处的代码执行完,ret指令把lr寄存器中的指令地址写入到pc寄存器中,返回继续执行
  • 条件域
    • EQ:equal,相等
    • NE:not equal,不相等
    • GT:greate than,大于
    • GE:greate equal,大于等于
    • LT:less than, 小于
    • LE:less equal,小于等于
  • 内存操作
    • load,从内存中读取数据 * ldr 立即数是正数 * ldur 立即数是负数 * ldp (p是pair的简称,一对)
    • store,往内存中写入数据
      • str、stur
      • stp
      • 零寄存器,里面存储的值是0
        • wzr(32bit,Word Zero Register)
        • xzr (64bit)

函数堆栈

  • 函数的类型
    • 叶子函数,函数内部有调用其他函数
    • 非叶子函数

生成汇编文件

  • xcun –sdk iphoneos clang -S -arch arm64 main.c -o main.s

LLDB调试方法,打印参数

  • po $x0:打印方法调用者
  • x/s $x1:打印方法名
  • po $x2:打印参数
  • po $x0** :打印寄存器中的值,直接打印寄存器不行,要加上美元符
  • x/s $x1:寄存器中存储的是字符串,将寄存器中的信息以字符串的格式打印出来

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

2583 文章
29 评论
84935 人气
更多

推荐作者

Jay

文章 0 评论 0

guowei007

文章 0 评论 0

2668157715

文章 0 评论 0

HY阳

文章 0 评论 0

想挽留

文章 30 评论 3