armv8 汇编 绝对地址赋值_ARMv8中branch指令分类、格式及用法

ARMv8虽然还没有出商用芯片,但是ARM内部已经有成型的模拟器了,其中ARMv8的Fast Models已经内测,虽然还没上市。目前已有ARMv8的Foundation Model可以用来测试ARMv8的应用程序。

一:ARMv8 Branch指令分类:

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

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

举例:编写汇编代码如下

main:

label:  nop

b label

ret

编译并且反汇编后:

0000000000400510 :

label():

400510:       d503201f        nop

400514:       17ffffff                        b       400510

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等等)

二:指令格式:

#################################################################################################

b ## mask: 0xfc000000 ##opcode: 0x14000000 ## ['ADDR_PCREL26']

|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|

imm26 after split: imm26

|0 |0 |0 |1 |0 |1 |A |A |A |A|A |A |A |A |A |A |A |A |A |A |A |A |A |A |A |A |A |A |A |A |A |A |

mask as follow:

|1 |1 |1 |1 |1 |1 |0 |0 |0 |0|0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |

A  - imm26

################################################################################################# CSDN的编辑器不好,对不齐,以上是branch指令的opcode

三:用法及解析

另外,上面代码例子中,为什么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

400518:       d65f03c0        ret

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

同理就能理解以下代码:

000000000040051c :

label2():

40051c:      d503201f        nop

400520:       d503201f        nop

400524:       d503201f        nop

400528:       17fffffdb       40051c

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

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

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

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

0000000000400510 :

$x():

400510:       14000003b       40051c

400514:       aa0203e1        mov    x1, x2

400518:       aa0203e1        mov    x1, x2

000000000040051c:

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值