assembly 如何在Apple Silicon(ARM64)上通过标签加载数据?

roejwanj  于 2023-05-29  发布在  其他
关注(0)|答案(1)|浏览(162)
  • LDR* 由于Apple的安全性思想而无法正常工作,但我如何加载,例如:
.data
.align 4
.mynumber: .quad   0x123456789ABCDEF0

我知道ADRP,但我不确定我是否理解它是如何工作的。
我已经这样做了(ADRP,@PAGE,@PAGEOFF取自其他来源):

.global _start

.text
_start: 
    ADRP    X2, arr1@PAGE
    ADD X2, X2, arr1@PAGEOFF

    mov     X0, #0      // Use 0 return code
    mov     X16, #1     // System call number 1 terminates this program
    svc     #0x80       // Call kernel to terminate the program

.data
.align 4
arr1:   .FILL   10, 4, 0
mynumber:   .quad   0x123456789ABCDEF0
myoctaword: .octa 0x12345678876543211234567887654321
m528fe3b

m528fe3b1#

“按标签加载数据”工作得非常好:

ldr x0, label

label:
    .8byte 0x0123456789abcdef

在达尔文上不起作用的是ldr x0, =...,因为这是语法糖:

ldr x0, addrof_label

label:
    .8byte 0x0123456789abcdef
addrof_label:
    .8byte label

由于label是一个静态编码的地址,它需要由动态链接器重定基,这会在尝试时崩溃进程,因为__TEXT段既被Map为r-x又被协同设计。
要获取某些标签的地址,可以使用adr

adr x0, label

label:
    .8byte 0x0123456789abcdef

但这只能在±1MiB范围内工作,此外,工具链只允许您在同一段内执行此操作,即__TEXT。对于一般情况,adrp+add是要走的路:

adrp x0, label@PAGE
add x0, x0, label@PAGEOFF

.data
label:
    .8byte 0x0123456789abcdef

但是,如果结果偏移量在范围内,您可以使用.loh AdrpAdd ...指令让链接器将其修复回adr+nop

L1:
adrp x0, label@PAGE
L2:
add x0, x0, label@PAGEOFF
.loh AdrpAdd L1, L2

.data
label:
    .8byte 0x0123456789abcdef

如果需要的话,adrp+ldr也可以这样做,同样,如果在范围内,.loh AdrpLdr ...可以将其转换为PC相关的ldr

相关问题