ARM汇编 - 写入内存 - 分段错误

3

在ARM汇编中写入内存时遇到了问题。

我正在使用树莓派(Raspbian)和GNU汇编器。

first.s:

.global main
.func main

main:
    ldr r5, =0x10000000
    mov r1, #19 
    str r1, [r5]
    bx lr

当我运行以上代码时:
pi@raspberrypi ~/assembly $ make first
as -o first.o first.s
gcc -o first first.o
pi@raspberrypi ~/assembly $ ./first ; echo $? > output.txt
Segmentation fault

正如您所看到的,出现了分段错误。输出文件output.txt保留了值139,我理解这是指分段错误。 难道内存地址无效吗? 我已经检查过数据手册,内存地址似乎没问题。

6
如果您在操作系统下运行,您只有虚拟地址,无法直接访问物理内存或内存映射设备。 - Jester
2
没有办法写入任意物理内存。当然,您可以为自己的内容分配内存,然后使用它。例如,您可以执行.lcomm myint, 4,然后ldr r5,=myint - Jester
@Jester,感谢您的建议。我以前没有使用过.lcomm,但我不确定它是否适合我的需求。我真正想做的是将寄存器的内容写入内存,然后从单独的C函数中读取该内存位置处的值。我假设C函数无法知道.lcomm保留的位置...对于这个问题我很抱歉。您有什么建议吗? - foaf
4
在你的C代码中声明 extern int myint,然后可以使用 .comm 代替,并使其成为全局变量。当然,你也可以切换到 .data 并使用各种数据定义指令之一,如果你将变量标记为 .global,或者在C代码中定义int并从汇编语言中引用它。 - Jester
好的,我会尝试一下。再次感谢@Jester。希望您不介意我稍后在这里发一个跟进问题。 - foaf
显示剩余2条评论
1个回答

0
在计算机系统中,有几种不同的“内存空间”类型。例如,在Windows系统上,有未提交、保留、只读、可执行等类型。写入任何标记为“保留”或指向无效内存地址的地址之外的内存部分将导致段错误。这是大多数现代系统的关键安全特性。我猜测您需要在写入之前预留内存,以便在您的努力中成功。
使用汇编语言中最简单的方法是创建一个数据段来预留内存。在许多汇编语言中,数据段前面是.data,但很久没有使用ARM汇编了,请验证一下。一旦您在数据段中预留了一小块内存,就可以轻松地获得“变量”的地址,并像您在示例中所做的那样对其进行写入。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接