如何解决如何在 ARM64 汇编代码中分配可写内存?
我正在尝试学习 ARM64。我正在 Apple M1 上组装。
我正在尝试分配可以写入的内存。我不断收到以下错误:
ld: Absolute addressing not allowed in arm64 code but used in '_main' referencing 'foo'
我的程序很简单:
// foo.s
.global _main
.align 2
_main:
ldr x0,=foo
.data
foo: .zero 8
我正在使用这个脚本来编译它:
#!/bin/bash
as foo.s -o foo.o && \
\
ld foo.o -o foo \
-arch arm64 \
-syslibroot `xcrun -sdk macosx --show-sdk-path` \
-lSystem
经过一些谷歌搜索后,我尝试为 ld 设置 -no_pie
但结果是:
ld: warning: -no_pie ignored for arm64
我不太确定发生了什么。
谢谢
我应用了该修复程序并编写了这个快速程序来测试它是否有效:
.global _main
.align 2
_main:
// Set x0 to the memory address of foo.
adrp x0,foo@PAGE
add x0,x0,foo@PAGEOFF
// Store 123 in foo.
mov x1,123
str x1,[x0]
// Load the contents of foo into x2.
ldr x2,[x0]
// Exit with a status code set to foo.
mov x0,x2
mov x16,1
svc 0
.data
foo: .zero 8
正如我所料,它以 123 的退出状态返回。
解决方法
您使用 .zero
部分中的 .data
分配了内存。现在你只需要加载它的地址就可以访问它。
与其尝试禁用它,不如编写与位置无关的代码。因此,不要尝试加载绝对地址,而是相对于程序计数器访问它们。
在中等大小的程序中(小于一兆字节左右的代码加上静态数据),你可以用
将foo
的地址加载到x0
中
adr x0,foo
adr
指令将立即数与程序计数器 pc
的值相加,并将结果留在目标寄存器中。汇编器和链接器可以确定 adr
指令的地址和 foo
的地址之间的差异,并将该差异编码为 adr
指令的立即数。
对于较大的程序,其中地址差异可能高达 4 GB 左右,您可以使用 adrp
的组合来获取高位,并使用 add
或加载/存储抵消。见What are the semantics of ADRP and ADRL instructions in ARM assembly?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。