我正在学习 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
段加载数据的解决方案。
为了将此问题标记为已解决,让我解释一下 Jester 和 Peter,他们在评论部分回答了我的问题。
.word
数据指令保存32位长的数据,我将该值加载到64位长的x
寄存器中。因此,更多的数据被加载到该寄存器中以完全填满它。要解决这个问题,我应该:
.quad
(64 位),因此数据和寄存器都匹配相同的大小。.word
(32 位),但将值加载到也是 32 位长的 w
寄存器。参考资料: