| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> ARM Cortex-A系列编程指南之ARMv8 A -- 第五章 ARMv8指令集介绍 -> 正文阅读 |
|
[嵌入式]ARM Cortex-A系列编程指南之ARMv8 A -- 第五章 ARMv8指令集介绍 |
ARMv8体系结构增加了64位指令集,是对现存的32位指令集的补充,被叫做A64(运行在AArch64运行状态下)。运行在AArch32运行状态下的指令集是A32和T32。 如果想详细了解A64的汇编语言,可以参考Documentation – Arm Developer,《Arm Compiler armasm User Guide Version 6.12》。 5.1 ARMv8指令集5.1.1 区分32位和64位A64指令在A64指令集的指令有2种形式,或者32位,或者64位。 1)寄存器以X开头,存储64bit的值 2)寄存器以W开头,存储32bit的值 当选了32位的形式: 1)右移或者反转,操作的是第31位,而不是63位 2)指令设置的条件标志,从低32位开始算 3)写W寄存器,X寄存器的高32位会被设为0 5.1.2 寻址当处理器在一个寄存器能存储64位值的时候,在一个程序里访问大内存就变得简单了。执行在32位核上的一个单线程,只能访问最大4GB的地址空间,其中高端地址部分会被预留给OS内核、库、外围设备等使用。内存空间的缺乏,意味着程序在执行的时候需要映射一些数据到内存空间之外。64位指针,有更大的寻址空间,避免了此问题。 其他寻址方面的改进包括 1)互斥访问(exclusive access) 几个寄存器同时被更新(保证一个操作的原子性)。 2)PC寄存器的相对寻址空间增加了 PC寄存器的常量加载有不超过±1MB范围的相对寻址空间。相对于A32指令集PC存器相关的加载过程,A64减少了数据缓冲池的数量,并且增加了函数之间数据缓冲池的共享程度。反过来,也减少了对I-cache和TLB的污染。 3)对地址不对齐的支持 除了互斥访问和有序访问,所有访问普通存储空间的加载和存储过程都支持使用未对齐的地址。这简化了向A64移植代码的难度。 4)块传输 在A64指令集,LDM、STM、PUSH、POP指令不再存在。 块传输可以使用LDP、STP,他们可以从连续的存储空间中读取、存储一对相互独立的寄存器值。 LDNP、STNP指令,用于提供流或非临时数据的指示,让数据不必要长期保存在cache中。 PRFM指令(预取内存指令),能够将预先载入的内容绑定到特定的cache等级。 5)Load/Store 所有的Load/Store指令支持一致的寻址模式,这样char、short、int、long都可以使用相同的方式进行处理。 浮点寄存器和NEON寄存器也和核心寄存器一样,使用相同的寻址模式,这样也比较方便的交替使用2个寄存器组。 6)对齐检查 当在AArch64运行模式下,额外地对齐检查操作将会在如下三个过程 5.1.3 寄存器64位程序调用标准(PCS, Procedule Call Standard)可以传最多8个参数(X0~X7),而A32和T32仅仅可以通过寄存器传4个参数,其他的通过堆栈进行。 PCS也定义了一个专用帧指针(FP:frame pointer),提高了可靠展开堆栈的可能性,降低了调试和调用图分析的难度。 不同的类型的长度,有一些标准: ?64位的Linux使用的是LP64标准。 1)零寄存器(WZR/XZR) a、它会被用在一些编程技巧中 b、不用立即数0,直接用零寄存器 c、空指令 2)堆栈指针 堆栈指针不能被所有的指令访问,一些形式的算数指令可以读或写当前的栈指针。这种操作通常用来在函数开始或结束的位置调整栈指针的位置。例如 ADD SP, SP, #256 // SP = SP + 256。 3)程序计数器 4)FP和NEON寄存器 目前有32个16位 NEON寄存器,之前是16个。浮点和NEON寄存器组中不同的寄存器尺寸之间有更简单的映射表,让这些寄存器更加易用。新的映射表让编译和优化器的建模和分析变得更容易。 5)寄存器变址寻址 base + index 乘 scale 5.2 C/C++内联汇编如何将汇编代码,集成在C、C++代码里呢?用asm关键字,例如:
#include <stdio.h>
int add(int i, int j)
{
? ? int res = 0;
? ? asm (
? ? ? ? "ADD %w[result], %w[input_i], %w[input_j]"
????????//Use `%w[name]` to operate on W
? ? ? ? // registers (as in this case).
? ? ? ? // You can use `%x[name]` for X
? ? ? ? // registers too, but this is the?default.
? ? ? ? : [result] "=r" (res)
? ? ? ? : [input_i] "r" (i), [input_j] "r" (j)
? ? ? ? );
????return res;
}
int main(void)
{
????????int a = 1;
????????int b = 2;
????????int c = 0;
????????c = add(a,b)
????????printf(“Result of %d + %d = %d\n, a, b, c);
}
通常的语法是:
asm(code [: output_operand_list [: input_operand_list [: clobber_list]]]);
在我们这个例子里:
code就是"ADD %w[result], %w[input_i], %w[input_j]"。
output_operand_list就是[result] "=r" (res)。
input_operand_list就是[input_i] "r" (i), [input_j] "r" (j)。
clobber_list为空。
在C、C++与汇编之间互相调用需要遵守AAPCS64规范,可以参考:Using Assembly Language with C (Using the GNU Compiler Collection (GCC)) 5.3 各个指令集之间进行切换在一个应用程序中,使用两种执行状态的代码是不可能的。 以A64 ARMv8写得代码,不能运行在ARMv7系列的处理器上。但是为ARMv7-A写得代码能够运行在ARMv8的AArch32运行状态。 可以总结如下: ========================================================================= 注意:本文为本人原创,版权所属为个人所有,欢迎转载,但是转载请注明出处。 ========================================================================= |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 12:52:30- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |