需要帮助找出 ARM 中的分段错误
Need help figuring out a segmentation fault in ARM
所以我最近收到了一个二年级计算机科学模块的项目,我们在那里学习计算机体系结构。我们被指示编写 ARM 汇编代码来输出 n=15 和 n=30 的斐波那契数列。
我试过在线查看多个资源,但 ARM 的使用并不广泛,2020 年也不再受支持。我已经能够编译 运行 我的代码,但是它告诉我“分段错误”并输出错误的数字 (139)。
上周末我一直被困,尝试了多次修复,但没有成功。如果有人能指导我正确的方向,或者帮助我找出我的逻辑或语法错误,那就太好了。我将 post 下面的代码,在此先感谢您!!!
.global main
.func main
main:
LDR R5,=0x50000000 ; load mem address
MOV R1,#5 ; number comparisons
.loop:
LDR R2,[R5] ; load 1st number
ADD R6, R5,#04 ; increment address to next number
LDR R3, [R6] ; load 2nd number
ADD R4, R2, R3
STR R4, [R6,#4] ;store in next mem location
MOV R5, R6
SUBS R1, #01 ; decrement counter
BNE .loop ; loop mechanism
NOP
.endfunc
BX LR
您的代码崩溃是因为您尝试 read/write 一个随机地址。这个crash被你的shell根据公式128+signal number翻译成exit status 139(SIGSEGV
是signal 11)
您通常不应简单地选择一些随机地址并将您的数据存储在那里。这几乎总是会崩溃,如果没有,该地址的内存仍然可能被程序中的其他内容使用。
要解决此问题,您应该显式分配一些内存并使用该内存区域的地址。最简单的方法是使用 静态内存分配 并将您需要的数据放在 .data
部分:
.section .data ; enter .data section
data: .int 0 ; first number
.int 1 ; second number
这里,data
是一个符号。你可以给它起任何你想要的名字,但它的名字在源文件中必须是唯一的。然后,您可以在程序中加载 data
的地址,而不是 hard-coding 0x50000000
:
ldr r5, =data ; load the address of data
请注意,如果要在定义变量后将代码放入文件中,则需要切换回 .text
部分。代码(即 程序文本 )总是进入 .text
部分。
.section .text ; switch back to the .text section
在文件的开头,当前部分隐式为 .text
部分,但在发出任何类型的代码或数据之前始终显式切换部分通常是个好主意。
也可以将未初始化的数据放在.bss
部分。如果您想分配一个数据数组并且不想输入那么多 .int
指令,这将特别有用。
.section .bss ; enter .bss section
data: .space 8 ; reserve 8 bytes of memory
与.data
部分相反,在.bss
部分不可能指定内存的初始值。初始值将始终是一系列零。
所以我最近收到了一个二年级计算机科学模块的项目,我们在那里学习计算机体系结构。我们被指示编写 ARM 汇编代码来输出 n=15 和 n=30 的斐波那契数列。
我试过在线查看多个资源,但 ARM 的使用并不广泛,2020 年也不再受支持。我已经能够编译 运行 我的代码,但是它告诉我“分段错误”并输出错误的数字 (139)。
上周末我一直被困,尝试了多次修复,但没有成功。如果有人能指导我正确的方向,或者帮助我找出我的逻辑或语法错误,那就太好了。我将 post 下面的代码,在此先感谢您!!!
.global main
.func main
main:
LDR R5,=0x50000000 ; load mem address
MOV R1,#5 ; number comparisons
.loop:
LDR R2,[R5] ; load 1st number
ADD R6, R5,#04 ; increment address to next number
LDR R3, [R6] ; load 2nd number
ADD R4, R2, R3
STR R4, [R6,#4] ;store in next mem location
MOV R5, R6
SUBS R1, #01 ; decrement counter
BNE .loop ; loop mechanism
NOP
.endfunc
BX LR
您的代码崩溃是因为您尝试 read/write 一个随机地址。这个crash被你的shell根据公式128+signal number翻译成exit status 139(SIGSEGV
是signal 11)
您通常不应简单地选择一些随机地址并将您的数据存储在那里。这几乎总是会崩溃,如果没有,该地址的内存仍然可能被程序中的其他内容使用。
要解决此问题,您应该显式分配一些内存并使用该内存区域的地址。最简单的方法是使用 静态内存分配 并将您需要的数据放在 .data
部分:
.section .data ; enter .data section
data: .int 0 ; first number
.int 1 ; second number
这里,data
是一个符号。你可以给它起任何你想要的名字,但它的名字在源文件中必须是唯一的。然后,您可以在程序中加载 data
的地址,而不是 hard-coding 0x50000000
:
ldr r5, =data ; load the address of data
请注意,如果要在定义变量后将代码放入文件中,则需要切换回 .text
部分。代码(即 程序文本 )总是进入 .text
部分。
.section .text ; switch back to the .text section
在文件的开头,当前部分隐式为 .text
部分,但在发出任何类型的代码或数据之前始终显式切换部分通常是个好主意。
也可以将未初始化的数据放在.bss
部分。如果您想分配一个数据数组并且不想输入那么多 .int
指令,这将特别有用。
.section .bss ; enter .bss section
data: .space 8 ; reserve 8 bytes of memory
与.data
部分相反,在.bss
部分不可能指定内存的初始值。初始值将始终是一系列零。