为什么使用 ADRP、ADD 和 LDR 指令加载的数据比预期的要大?

问题描述 投票:0回答:1

我正在学习 Apple M1 arm64 的汇编,并注意到尝试从数据段上的标签加载数据时出现一些奇怪的情况。它似乎不仅加载了我要求的标签的内容

var1
,还加载了靠近它的下一个标签
var2

.global _start

_start:
    mov x0, #0
    mov x1, #0

    // In this first part we load data from memory.
    // -------------

    // Load var1 from the memory, and set its address to X0 register.
    adrp X0, var1@PAGE      // address of var1 word 4k page
    add X0, X0, var1@PAGEOFF    // offset to var1 within the page

    // Get the value from the address memory stored on X0 register.
    // When using `ldr` with brackets loads the actual value
    // similar to dereferencing a pointer.
    ldr X1, [X0]

    // In this second part we update data from memory.
    // -------------

    // Set 3 to the X2 register.
    mov X2, #3     // <--- This is the line 38 where I add a breakpoint

    // Load the memory address for the vaX2 data variable.
    adrp X3, var2@PAGE
    add X3, X3, var2@PAGEOFF

    // Store X2 register value to the memory address on the X3 register.
    str X2, [X3]

    // Exit program
    mov X0, 0       // 0 status code
    mov X16, #1
    svc #0x80

.data
var1: .word 5
var2: .word 6

这就是我构建它的方式:

as lesson03.s -g -o lesson03.o
ld lesson03.o -o lesson03 -l System -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _start -arch arm64

这就是我调试

X1
值的方式:

lldb lesson03

(lldb) b lesson03.s:38

Breakpoint 1: where = lesson03`start + 20, address = 0x0000000100003f8c
(lldb) run

(lldb) re read x1
      x1 = 0x0000000600000005

我本来期望得到

0x0000000000000005
(十进制
5
),但正如我们所看到的,它是
0x0000000600000005
(十进制
25769803781
),它似乎正在从
<var2=00000006,var1=00000005>
一起加载数据。

有谁知道为什么会发生这种情况以及如何解决它?顺便说一句,我正在寻找一种仍然可以从

.data
段加载数据的解决方案。

assembly arm64 mach-o
1个回答
0
投票

为了将此问题标记为已解决,让我解释一下 Jester 和 Peter,他们在评论部分回答了我的问题。

.word
数据指令保存32位长的数据,我将该值加载到64位长的
x
寄存器中。因此,更多的数据被加载到该寄存器中以完全填满它。要解决这个问题,我应该:

  • 使用
    .quad
    (64 位),因此数据和寄存器都匹配相同的大小。
  • 或者,仍然使用
    .word
    (32 位),但将值加载到也是 32 位长的
    w
    寄存器。

参考资料:

© www.soinside.com 2019 - 2024. All rights reserved.