MOV(wide immediate)
MOV 可以将一个立即数移动到寄存器中。
MOV X0, #0x1234 对应的汇编代码为:80 46 82 D2
看手册可知,0x1234 的值储存在 5 - 20 位里面。
汇编指令对应的二进制为:
其中最低5为都是0,所以寄存器是 X0 寄存器。
5-20 位的值分别是 4 3 2 1,刚好就是 0x1234。
这种 mov 指令还是比较常见的,但是由于指令的限制,它只能描述16位的立即数。
看另外的一个例子:
MOV X0, #0x80000000 这条指令的立即数显然已经超过了16位,这又是咋回事呢?这是 MOV 指令的另一种形式,由于
#0x80000000 这样的立即数实际的有效位数很少,所以ARM指令集对其表示做了优化。手册里面有说到,MOV 实际上等同于 MOVZ:

而 MOVZ 是支持 shift 写法的:
所以上面的汇编实际上等同于:
汇编指令对应的二进制为:
看其 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:汇编指令对应的二进制为:
所以,Rd 的值是 0,表示 X0 寄存器,Rm 的值是1,表示 X1 寄存器。
顺便说一下 ORR 指令:

是将寄存器中值按位做“或”操作。
ORR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}Xm还可以做移位操作,具体移动多少位由 imm6 决定,怎么移动由 shift 决定。

MOVK
由于ARM64指令集是定长的4字节指令,这就决定了它无法在指令里面描述一个任意的数字,比如:0x123456789,这个就无法在指令中表示。
那么,当我们在程序中使用到这个数字的时候,arm64指令集是如何处理的呢?
我们写一个例子看看:
查看汇编代码:
我们只看 X1 相关的指令,它分为3个步骤:
通过数据的拼接来达成目标,非常的合理。










