汇编基础(2) -- ARM64

简介

ARM架构中,ARM64(也称为AArch64)是一种64位处理器架构,它是ARMv8指令集的一部分。与之前的32位ARM架构相比,ARM64提供了更大的寄存器容量、更广阔的地址空间和更高的计算能力。

64位版本的指令集和32位版本的指令集有一些区别,这些区别主要涉及到以下几个方面:

  • 寄存器:ARM64架构提供了31个通用寄存器,每个寄存器的容量为64位。相比之下,32位ARM架构只有16个通用寄存器,每个寄存器的容量为32位。

  • 操作数大小:在ARM64架构中,所有数据都是以64位的形式进行处理。相比之下,32位ARM架构只能处理32位的整数和单精度浮点数。

  • 内存地址空间:在ARM64架构中,虚拟地址空间最大可达256TB,可以同时支持多达4亿个进程。相比之下,32位ARM架构只支持最大4GB的虚拟地址空间,并且最多只能支持4096个进程。

  • 执行速度:由于ARM64架构的寄存器容量更大、操作数更大,所以在大多数情况下,ARM64指令集的执行速度比32位ARM指令集更快。

  • 兼容性:ARM64架构与32位ARM架构不兼容,因此32位的应用程序不能在ARM64架构的处理器上直接运行。

寄存器

寄存器说明
x0-x7通用寄存器,用于函数参数传递和返回值存储
x8通用寄存器,可用作附加参数传递
x9-x15通用寄存器,用于临时数据存储
x16通用寄存器,可用作线程/进程本地数据存储区域指针
x17通用寄存器,可用作异常链接寄存器
x18通用寄存器,可用作平台相关寄存器
x19-x28通用寄存器,用于临时数据存储
x29 (fp)帧指针寄存器,用于保存当前函数的帧指针
x30 (lr)链接寄存器,用于保存返回地址
sp栈指针寄存器,指向当前栈顶位置
pc程序计数器寄存器,存储下一条要执行的指令的地址
cpsr当前程序状态寄存器,保存处理器的当前状态信息,如条件标志位、中断使能位、处理模式等
nzcv零、负、进位和溢出条件标志位,记录上一条指令结果的状态
f0-f31浮点寄存器,用于浮点运算
v0-v31矢量寄存器,用于SIMD(单指令多数据)操作
w032位宽的低位部分,对应于x0寄存器
s016位宽的低位部分,对应于x0寄存器的低16位
b08位宽的最低字节部分,对应于x0寄存器的最低字节

指令

指令类型示例指令说明
数据传输LDR X0, [X1]从内存中加载数据到寄存器
STR X0, [X1]将寄存器中的数据存储到内存
算术运算ADD X0, X1, X2将两个寄存器中的值相加
SUB X0, X1, X2将两个寄存器中的值相减
逻辑运算AND X0, X1, X2将两个寄存器中的值进行按位与
ORR X0, X1, X2将两个寄存器中的值进行按位或
控制流B label分支到标签处执行
BL label分支并且保留返回地址
CMP X0, X1比较两个寄存器中的值
BEQ label如果上一次比较结果为相等,则分支到标签处执行
B label无条件跳转到标签处执行
BL label分支与链接 跳转到标签处执行,并保存返回地址
BR Xn无条件跳转到寄存器Xn中存储的地址
B.cond label根据特定条件进行跳转
BLR Xn无条件跳转到寄存器Xn中存储的地址,并保存返回地址
BR Xn无条件跳转到寄存器Xn中存储的地址,并恢复返回地址及上下文
BLR Xn跳转到寄存器Xn中存储的地址,并保存返回地址及上下文
乘法和除法MUL X0, X1, X2将两个寄存器中的值相乘
SDIV X0, X1, X2将两个寄存器中的值相除
浮点运算FADD D0, D1, D2将两个浮点寄存器中的值相加
FSUB D0, D1, D2将两个浮点寄存器中的值相减
FMUL D0, D1, D2将两个浮点寄存器中的值相乘
FDIV D0, D1, D2将两个浮点寄存器中的值相除
压栈STP X0, X1, [SP, #-16]!将两个寄存器的值压入栈中
STR X0, [SP, #-8]!将一个寄存器的值压入栈中
出栈LDP X0, X1, [SP], #16从栈中弹出两个寄存器的值
LDR X0, [SP], #8从栈中弹出一个寄存器的值
设置栈指针MOV SP, X0将指定寄存器的值设置为栈指针
获取栈指针MOV X0, SP将栈指针的值保存到指定寄存器

实例分析

  • 包含if语法的函数:
int ifFunction(int x, int y) {
    int result;
    if (x > y) {
        result = x + y;
    } else {
        result = x - y;
    }
    return result;
}

ifFunction:
    cmp x0, x1      // 比较 x 和 y
    ble else_label  // 如果 x <= y,跳转到 else_label 标签处
    add x0, x0, x1  // 如果 x > y,执行 x + y
    ret             // 返回结果
else_label:
    sub x0, x0, x1  // 如果 x <= y,执行 x - y
    ret             // 返回结果

  • 包含for语法的函数:
int forFunction(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
        sum += i;
    }
    return sum;
}

forFunction:
    mov w1, 1       // 将 1 赋值给寄存器 w1,作为循环计数器 i 的初始值
    mov w0, 0       // 将 0 赋值给寄存器 w0,作为累加和 sum 的初始值
loop:
    add w0, w0, w1  // 累加计数器 i 的值到累加和 sum
    add w1, w1, 1   // 计数器 i 自增 1
    cmp w1, x0      // 比较计数器 i 和 n 的值
    ble loop        // 如果 i <= n,跳转到 loop 标签处继续循环
    ret             // 返回累加和 sum

  • 包含switch语法的函数:
int switchFunction(int x) {
    int result;
    switch (x) {
        case 1:
            result = 10;
            break;
        case 2:
            result = 20;
            break;
        case 3:
            result = 30;
            break;
        default:
            result = -1;
    }
    return result;
}

switchFunction:
    cmp w0, 1       // 比较寄存器 w0(x)的值与每个 case 的值
    b.eq case_1     // 如果相等,跳转到 case_1 标签处
    cmp w0, 2
    b.eq case_2
    cmp w0, 3
    b.eq case_3
    mov w0, -1      // 默认情况下,将 -1 赋值给寄存器 w0(result)
    ret
case_1:
    mov w0, 10      // 如果 x == 1,将 10 赋值给寄存器 w0(result)
    ret
case_2:
    mov w0, 20      // 如果 x == 2,将 20 赋值给寄存器 w0(result)
    ret
case_3:
    mov w0, 30      // 如果 x == 3,将 30 赋值给寄存器 w0(result)
    ret

参考

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: arm-none-linux-gnueabi-gcc 是一种编译器,它可以用来编译程序以在没有操作系统的 Linux on ARM 架构设备上运行。 "arm" 指的是这些设备使用的处理器架构,"none" 指的是没有操作系统,"linux" 指的是目标环境是 Linux,"gnueabi" 指的是使用 GNU 的 Embedded Application Binary Interface。 ### 回答2: arm-none-linux-gnueabi-gcc是一种适用于ARM处理器的GNU编译器,它适用于运行Linux操作系统的ARM处理器。它是一种交叉编译器,可以在一种操作系统上编译代码并在另一种操作系统上运行该代码。 arm-none-linux-gnueabi-gcc能够编译C、C++和汇编语言。它还支持各种优化选项,并可以生成目标文件、可执行文件以及动态链接库。 arm-none-linux-gnueabi-gcc使用GNU工具链作为其基础环境,该工具链包含了众多的编译器、调试器等,可以实现完整的软件开发流程。它还支持多种架构和操作系统,包括ARM、x86、MIPS和PowerPC等处理器。 在嵌入式系统开发中,通常需要使用交叉编译器来开发和调试嵌入式系统的应用程序,因为该应用程序将在另一种体系结构和操作系统上运行。arm-none-linux-gnueabi-gcc正是一种非常流行的交叉编译器,它适用于ARM架构的嵌入式系统,是很多嵌入式系统开发者必备的工具之一。 总之,arm-none-linux-gnueabi-gcc是一种适用于ARM处理器的GNU编译器,它可以在Linux操作系统上运行,并可以生成目标文件、可执行文件以及动态链接库。它使用GNU工具链作为基础环境,支持多种架构和操作系统,在嵌入式系统开发中有着广泛的应用。 ### 回答3: arm-none-linux-gnueabi-gcc是一种交叉编译器,它用于将C、C++等高级语言编写的代码编译成ARM指令集的可执行文件,以便在ARM架构的嵌入式系统上运行。 其中,arm表示目标平台为ARM架构,none表示针对的是裸机环境,即没有操作系统支持的单片机或嵌入式设备;linux表示编译生成的可执行文件是在Linux系统上运行的,gnueabi表示使用GNU工具链和嵌入式应用程序二进制接口(EABI)。 arm-none-linux-gnueabi-gcc作为一种交叉编译器,它具有比较高的灵活性和可移植性,可以在主机环境中生成适用于嵌入式设备的应用程序。使用该编译器可以大大简化程序的开发过程,同时也可以提高程序的性能和效率。 在使用arm-none-linux-gnueabi-gcc进行编译时,需要注意一些问题,如目标平台的架构、芯片类型、系统版本等。此外,还需要了解所编写的程序所需要的库文件,并将其链接到目标文件中。 总之,arm-none-linux-gnueabi-gcc是一种重要的编译器,它为嵌入式系统开发提供了强大的编译能力,为开发人员提供了方便快捷的开发方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值