关于ARMv8指令的几个问题

NOTE:以下内容只针对ARMv8。

问题一:ARMv8 branch指令格式及用法(《ARMv8ISA overview》中 page 25有相关叙述):

1、 无条件分支+立即数:直接跳转到某地址,不能跳转到寄存器

指令有两个:”b label”  ”bl label”。在编译过程,编译器会将label翻译成立即数。

举例:编写汇编代码如下

main:

     label:  nop

      b label

      ret

编译并且反汇编后:

0000000000400510 <main>:

label():

  400510:       d503201f        nop

  400514:       17ffffff                        b       400510 <main>

      400518:       d65f03c0        ret

2、 无条件分支+寄存器:

blr   Xm:跳转到由Xm目标寄存器指定的地址处,同时将下一条指令存放到X30寄存器中。例如:blr  x20.

br      Xm:跳转到由Xm目标寄存器指定的地址处。不是子程序返回

ret     {Xm}:跳转到由Xm目标寄存器指定的地址处。是子程序返回。Xm可以不写,默认是X30.

3、 条件分支:所有条件分支的跳转目标都是立即数!

ARMv8的条件分支写法:b.cond   label。其中cond是条件码共十六个(EQ,NE,CS等等)

问题二:ARMv8指令分类:

关于ARMv8的指令,在《ARMv8ISA overview》中做了分类,5.2章——5.6章是INT型指令,5.7是浮点指令,5.8是SIMD(即ARMv7中提到的NEON)指令。

关于SIMD指令如何操作,在5.8节有简单介绍,建议先看下4.4.2节关于FP/SIMD寄存器的说明。

另外,INT指令与FP指令之间的操作是针对不同的寄存器,所有两者之间没多少关系,至多就是INT型指令修改了寄存器内容,FP指令将修改后的寄存器当做源操作数读取。

问题三:

1、 ARMv8有没有两个目的操作数的指令?

答:有。例如LDP指令,从内存某地址处加载两个字到目的寄存器中,用法:LDP Wt1, Wt2, addr。

2、 ARMv8中源操作数超过三个的指令及分类:

(1)    扩展寄存器类操作,如:ADD   X1, X2, W3, UXTB #2

这里把UXTB和#2分别当做一个源操作数。

(2)    移位寄存器类操作,如:ADD         W1,W2,W3, lsl #2

目前能确定的只有这两类,最多不超过四种类型。如果需要我会做出详细的表。

另外,关于问题一中,为什么b指令的base opcode是0x14000000,而“b   label”指令翻译成二级制是0x17ffffff的解答如下:

Branch指令是相对当前pc的分支指令。

1、 在ARMv8中,相对于当前b指令向后跳转时,编译器生成指令的二进制encoding(即b指令最终生成的二进制代码)的过程如下:

向后跳转时,branch指令将除base opcode之外的位全部置一,然后做减法如下:

指令的Encoding = (0x14000000 | 0x03ffffff)—(当前b指令所在的指令地址—branch指令的目标地址)/4—1

即当前b指令地址与目标地址做差后整出4(因为是32位地址),再减一。

label():

  400510:       d503201f        nop

  400514:       17ffffff                        b       400510 <main>

      400518:       d65f03c0        ret

上面的例子中,b指令所在地址为400514,label所在的地址是400510(label只是个标签,不占用空间,其指示的是离自己最近的下一条指令地址),根据上述公式能得到encoding=0x17ffffff—(400514—400510)/4=0x17ffffff.

同理就能理解以下代码:

000000000040051c <label2>:

label2():

  40051c:      d503201f        nop

  400520:       d503201f        nop

  400524:       d503201f        nop

  400528:       17fffffd       
b       40051c <label2>

Encoding=0x17ffffff—(400528—40051c)/4—1= 0x17ffffff—2 = 17fffffd       

2、理解了向后跳转,则向前跳转是同理的:

向前跳转时,branch指令将除base opcode之外的位全部置零,然后做加法如下:

指令的Encoding = (0x14000000 &0xfc000000)+(branch指令的目标地址—当前b指令所在的指令地址)/4

0000000000400510 <main>:

$x():

  400510:       14000003       
b       40051c <label2>

  400514:       aa0203e1        mov    x1, x2

  400518:       aa0203e1        mov    x1, x2

 

000000000040051c <label2>:

 

Encoding=0x14000000 + (40051c—400510)/4 = 0x14000000 + 3=0x14000003

 

(其他体系结构暂时没做过测试,不过估计应该一样)

关于ARMv8指令的几个问题

时间: 2024-08-13 09:50:11

关于ARMv8指令的几个问题的相关文章

从编译器源代码中提取ARMv8的指令编码

2012年11月份的资料,之前ARMv8手冊还没公布,我想办法从编译器的binutils中提取出了全部ARMv8指令的二进制编码,之前不能随便发,如今相当于解禁了^_^. 问题1:提取ARMv8的指令编码 答:ARMv8指令的opcode能够在支持ARMv8的编译器binutils中找到,该工具能在网上找到,见參考资料[1],或者在[1]中搜索aarch64_opcode_table. 为了说明指令编码细节.现将网页中部分内容摘录例如以下: 1208 struct aarch64_opcode 

提取ARMv8的指令编码

2012年11月份的资料,之前ARMv8手册还没发布,我想办法从编译器的binutils中提取出了所有ARMv8指令的二进制编码,之前不能随便发,现在相当于解禁了^_^. 问题1:提取ARMv8的指令编码 答:ARMv8指令的opcode可以在支持ARMv8的编译器binutils中找到,该工具能在网上找到,见参考资料[1],或者在[1]中搜索aarch64_opcode_table. 为了说明指令编码细节,现将网页中部分内容摘录如下: 1208 struct aarch64_opcode aa

ARM64编译工具链下载

下面是自制的用于编译ARMv8指令的交叉编译工具链: 1.运行在PC上,支持SVE指令,不支持SVE ACLE,版本GCC9.2 https://pan.baidu.com/s/1_NnwajWCelT3rRUuM-yl6Q 2.运行在Qemu+Ubuntu18.04+ARM64,支持SVE ACLE,版本GCC9.0 https://pan.baidu.com/s/1qHeKnH5MiTCw_v9GnRJwJg 3.运行在Firefly RK3399 + Ubuntu16.04,支持SVE A

ARMV8 datasheet学习笔记4:AArch64系统级体系结构之编程模型(4)- 其它

1. 前言 2.可配置的指令使能/禁用控制和trap控制 指令使能/禁用 当指令被禁用,则这条指令就会变成未定义 指令Trap控制 控制某条或某些指令在运行时进入陷阱,进入陷阱的指令会产生trap异常,路由规则如下: (1)当前为EL1,则陷阱异常传递给EL1(HCR_EL2.TGE定义为1时,会路由到EL2); (2)当前为EL2,则陷阱异常传递给EL2; (3)当前为EL3,则陷阱异常传递给EL3; 3. 系统调用 SVC 默认情况下SVC产生supervisor call,同步异常目标级别

ARMv8 Linux内核异常处理过程分析

NOTE:为了方便大家阅读,制作了PDF版文档.下载请猛戳这里 老样子,为了赚点积分下载其它人的文件,下载以上资料须要资源分2分. 假设没有积分请留言全部文档,留下邮箱就可以. 看了Linaro提供的开源ARMv8 Linux内核源代码,发现ARMv8异常处理与ARMv7及之前的架构有所不同,简单分析. LinaroARMv8工程:http://www.linaro.org/engineering/engineering-projects/armv8 1.1 Linux内核异常处理相关文件 Li

关于ARMv8另外几个问题

问题1:支持ARMv8的Linux内核异常向量地址在哪? 答:异常向量基地址在0xffffffc000081800.通过查看编译后的linux内核的System.map文件,能确定异常向量表的基地址.通过反汇编生成的支持armv8的linux内核也可以证实.Armv8的异常向量表的定义在内核的arch/arm/kernel/entry.S中,将其摘录如下: /*  * Exception vectors.  */         .macro ventry  label         .ali

ARMv8 Linux内核源码分析:__flush_dcache_all()

1.1 /* *  __flush_dcache_all() *  Flush the wholeD-cache. * Corrupted registers: x0-x7, x9-x11 */ ENTRY(__flush_dcache_all) //保证之前的访存指令的顺序 dsb sy //读cache level id register mrs x0, clidr_el1           // read clidr //取bits[26:24](Level of Coherency f

ARMV8 datasheet学习笔记4:AArch64系统级体系结构之系统级存储模型

1.前言 关于存储系统体系架构,可以概述如下: 存储系统体系结构的形式 VMSA 存储属性   2. 存储系统体系结构 2.1.    地址空间 指令地址空间溢出 指令地址计算((address_of_current_instruction) + (size_of_executed_instruction))超过0xFFFF FFFF FFFF FFFF,PC变成不可知 2.2    Cache支持 Caches的一般行为 (1)Cache中已解锁的项不会一直驻留在cache; (2)Cache

ARMV8 datasheet学习笔记4:AArch64系统级体系结构之VMSA

1. 前言 2. VMSA概述 2.1 ARMv8 VMSA naming VMSAv8 整个转换机中,地址转换有一个或两个stage VMSAv8-32 由运行AArch32的异常级别来管理 VMSAv8-64 由运行AArch64的异常级别来管理 2.2 某些异常级别使用AArch32的ARMv8 VMSA EL3运行AArch32时的地址转换stages和转换regimes; EL3运行AArch64时任何运行AArch32的异常级别的的地址转换stages和转换regimes; 当EL0