为什么下面的48位ADDRESS是用mock加载的?

Why is the following 48bit ADDR loaded with with movk?

我在网上看到这个并且在 64 位代码中看到了以下内容。

movz x0, #:abs_g2:foo         
movk x0, #:abs_g1_nc:foo        
movk x0, #:abs_g0_nc:foo

为什么不做一个

mov x0, foo

这是针对 32 位机器的吗?我​​在 64 位代码中看到它的原因是为了向后兼容?

每条 AArch64 指令的长度都是 32 位。因此,space 不足以将 64 位地址放入一个。像 mov x0, foo 这样的指令只有在 foo 是一个 16 位数字(可选地左移 16、32 或 48 位)或其他各种可能的立即数之一时才有可能。

要加载 48 位地址,必须从文字池中加载地址(加载会产生额外的延迟)或在三个单独的加载中组装到内存中。

如果要加载的地址要与二进制文件一起重定位,则可以使用 ADRP 指令从当前位置加载 ±4 GB 范围内的 4 kB 对齐地址可以使用单独的 ADD 指令或在许多情况下在加载或存储期间使用位移来添加 12 位立即数(在当前位置的 4 GB 内形成任意地址)。