ARM64汇编05 - MOV系列指令

MOV(wide immediate)

MOV 可以将一个立即数移动到寄存器中。

.text:0000000000000834 80 46 82 D2                   MOV             X0, #0x1234             ; Keypatch modified this from:

MOV X0, #0x1234 对应的汇编代码为:80 46 82 D2

看手册可知,0x1234 的值储存在 5 - 20 位里面。

汇编指令对应的二进制为:

80 46 82 D2 ->
D2 82 46 80 ->
11010010 10000010 01000110 10000000 ->
1 10 100101 00 0001 0010 0011 0100 00000

其中最低5为都是0,所以寄存器是 X0 寄存器。

5-20 位的值分别是 4 3 2 1,刚好就是 0x1234。

这种 mov 指令还是比较常见的,但是由于指令的限制,它只能描述16位的立即数。

看另外的一个例子:

.text:0000000000000834 00 00 B0 D2                   MOV             X0, #0x80000000

MOV X0, #0x80000000 这条指令的立即数显然已经超过了16位,这又是咋回事呢?

这是 MOV 指令的另一种形式,由于 #0x80000000 这样的立即数实际的有效位数很少,所以ARM指令集对其表示做了优化。

手册里面有说到,MOV 实际上等同于 MOVZ:

而 MOVZ 是支持 shift 写法的:

MOVZ <Xd>, #<imm>{, LSL #<shift>}

所以上面的汇编实际上等同于:

MOVZ X0, #0x8000, LSL #16

汇编指令对应的二进制为:

00 00 B0 D2 ->
D2 B0 00 00 ->
11010010 10110000 00000000 00000000 ->
1 10 100101 01 1000 0000 0000 0000 00000

看其 hw 对应的位是 01,所以需要将 0x8000左移 1*16 位,得到 0x80000000。

hw 表示的是左移的位数,为 16 * (0~3)。

MOV (register)

MOV 可以将寄存器的值赋值给另一个寄存器。

Rm 与 Rd 都占据了5位,刚好可以描述所有的寄存器,MOV <Xd>, <Xm>

shift 有2位,这里固定是零值。imm6 与 Rn 也都是固定的值。

MOV 有个别名指令,ORR,它可以用到 shift,imm6,Rn的值。

看一个指令,MOV X0, X1

E0 03 01 AA                   MOV             X0, X1

汇编指令对应的二进制为:

E0 03 01 AA ->
AA 01 03 E0 ->
10101010 00000001 00000011 11100000 ->
1 01 01010 00 0 00001 000000 11111 00000

所以,Rd 的值是 0,表示 X0 寄存器,Rm 的值是1,表示 X1 寄存器。

顺便说一下 ORR 指令:

是将寄存器中值按位做“或”操作。

ORR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}

Xm还可以做移位操作,具体移动多少位由 imm6 决定,怎么移动由 shift 决定。

MOVK

由于ARM64指令集是定长的4字节指令,这就决定了它无法在指令里面描述一个任意的数字,比如:0x123456789,这个就无法在指令中表示。

那么,当我们在程序中使用到这个数字的时候,arm64指令集是如何处理的呢?

我们写一个例子看看:

uint64_t num = 0x123456789abc;
printf("num = %llx\n", num);

查看汇编代码:

.text:00000000000008AC 81 57 93 D2                   MOV             X1, #0x9ABC
.text:00000000000008B0 00 00 00 90                   ADRP            X0, #aNumLlx@PAGE       ; "num = %llx\n"
.text:00000000000008B4 01 CF AA F2                   MOVK            X1, #0x5678,LSL#16
.text:00000000000008B8 00 00 24 91                   ADD             X0, X0, #aNumLlx@PAGEOFF ; "num = %llx\n"
.text:00000000000008BC 81 46 C2 F2                   MOVK            X1, #0x1234,LSL#32

我们只看 X1 相关的指令,它分为3个步骤:

MOV             X1, #0x9ABC
MOVK            X1, #0x5678,LSL#16
MOVK            X1, #0x1234,LSL#32

通过数据的拼接来达成目标,非常的合理。

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值