zoukankan      html  css  js  c++  java
  • 关于ARMv8指令的几个问题

    版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/qianlong4526888/article/details/27512629

    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指令的目标地址)/41

    即当前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

     

    (其它体系结构临时没做过測试,只是预计应该一样)

  • 相关阅读:
    Q12:app在iPhone上执行正常,iPad上出现黑边问题解决方式
    SPOJ 104 Highways 最小生成树计数
    微信支付 常见报错
    oracle创建表空间、用户、和权限配置
    Android Matrix图像变换处理
    java项目部署到weblogic上后,某些浏览器无法取得session值
    简介redis以及ubuntu和windows下怎样安装redis和配置文件具体解释
    Melo作为程序猿的2016年
    软件架构,WEB
    软件架构,WEB
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10524580.html
Copyright © 2011-2022 走看看