• ARM64汇编基础


    ARM64汇编基础

    主要内容

    到目前为止,大部分的移动设备都是64位的arm架构,一直想抽个时间系统学习下,这个周末就专门来学习下。毕竟两天的时间,也只是简单的入门了解下,为后续工作和学习打下基础。

    本次学习的主要内容包括寄存器、指令系统以及堆栈函数相关的知识,了解这些知识后,后面就可以扩展进行学习了。话不多说,接下来介绍这两天的学习内容。

    主要的寄存器

        学习任何一门汇编语言,可能都需要了解有哪些寄存器。Arm64主要有以下几类寄存器。

    1. 通用寄存器

    通用寄存器包括64位的x0~x28,32位的版本叫做w0~28。w0~28是x0~x28的低32位版本。

    X0~x7通常用来存储函数参数,更多的参数通过栈来传递,x0用作返回值。

    1. 程序寄存器

        程序寄存器也叫程序计数器,记录CPU当前执行的是哪条指令,换句话说就是存储这当前cpu正在执行的指令地址。类似于x86汇编的eip寄存器。

    1. 堆栈指针寄存器

         这类寄存器包括两个,一个是叫做sp(stack pointer),另一个叫做fp(frame pointer),也就是x29。这两个寄存器指向的地址确定了当前函数可以访问的栈空间大小。

    1. 链接寄存器

        lr(Link Register),也就是x30,它的作用就是存储着函数的返回地址。

    1. 程序状态寄存器

    cpsr(Current Program Status Register),顾名思义就是记录者程序中的一系列状态。例如cmp指令结束后将比较结果存储在这个寄存器相关的标志位中。Cpsr寄存器的标志位布局如下图所示:

    1. 零寄存器

    wzr 32位

    xzr 64位,这两个寄存器中都是存储的0,用来清零操作,如指针和其它类型的变量清零。

    调试方法

    前面介绍了主要的寄存器后,我们简单介绍下调试方法,对主要的寄存器以及内存有初步的了解。由于本人相对对于lldb比较了解一点,就使用lldb为例。

    1. 查看寄存器

    register read 查看所有寄存器

    register read x0

    register read w0 查看x0的低32位版本

    register write x0 0x6388 往寄存器x0写入0x6388

    1. 查看变量的地址

    p &a 查看变量a对应的内存地址

    1. 查看地址的内存数据

    x &a 查看变量a对应地址内存地址的内容

    x 0x3442 查看地址0x3442的内容

    1. 单步调试

    si

    1. 逐指令调试

    si

    1. 继续执行

    c

    主要的指令

    arm64的指令包括所有变种的话非常多,因为我是主要关注软件方面,嵌入式方面不了解,所以个人觉得了解的指令不需要太多酒可以了。

    1. ret指令

    函数返回,它的本质是将lr寄存器赋值到pc寄存器。

    1. mov指令

    数据传送指令,mov指令只能操作寄存器,例如mov x1, x0

    1. add和sub

    加法和减法,比较简单

    1. b和bl指令

    b指令是无条件跳转,b指令也可以带上条件,如EQ\NE\GT\LT,根据cpsr寄存器中的标志为决定是否跳转。

    Bl指令是带返回的跳转指令,它所做的事情如下:

    1. 将下一条指令的地址存储到lr(x30)寄存器中
    2. 跳转到标记处开始执行代码
    1. cmp指令

    cmp指令比较两个寄存器中值的大小,比较的结果影响cpsr寄存器中相关的标记位。如N和Z位。例如:

    cmp x0, x1

    1. 内存加载指令,ldr,ldur ,ldp

    将内存中的数据加载到寄存器中,如

    ldr x0, [x1]

    ldur x0, [x1, #0x4]

    ldur x0, [x1, #0x4]!

    ldur x0, [x1] , #0x4!

    ldur x0, [x1,x2]

    一般情况下,ldr用于正向的偏移地址,ldur用于负向的偏移地址

    ldp ,p是pair的意思。

    1. 内存存储指令,str, stur, stp

    将寄存器的值写入内存的指令,用法和ldr指令类似。

    C函数的实现

        C语言函数实现,分为叶子函数和非叶子函数,函数的参数和返回值前面的通用寄存器已经介绍,现在是介绍叶子和非叶子函数的实现。

    叶子函数指没有调用其它函数的函数。叶子函数开头是分配函数的栈空间,结束的时候回收栈空间,一个典型的过程如下:

    非叶子函数指中间有调用其它函数的函数,一个典型的叶子函数如下所示:

    至此,arm64汇编的基础知识就介绍完毕,相信有了这些基础之后,后面的工作和学习会更有针对性的去查相关资料。

  • 相关阅读:
    P4343 [SHOI2015]自动刷题机-二分的两种情况
    MySQL之账号管理、建库以及四大引擎+案例
    自动驾驶学习笔记(四)——变道绕行仿真
    Linux、docker、kubernetes、MySql、Shell运维快餐
    Windows使用命令查看端口号占用情况并关闭进程
    MySQL之存储引擎
    Artstudio Pro Mac(绘图和图片编辑)
    Nginx学习笔记02——安装部署Nginx
    Elasticsearch:什么是余弦相似度?
    集合和泛型
  • 原文地址:https://blog.csdn.net/zhouxuguang236/article/details/132953101