问题描述
所以我最近收到了一个第二年计算机科学模块的项目,我们在那里进行计算机体系结构设计。我们被要求编写ARM汇编代码,以输出n = 15和n = 30的斐波那契数列。
我已经尝试过在线检查多种资源,但是ARM的使用不那么广泛,在2020年也不再受支持。我已经能够编译并运行我的代码,但是它告诉我“分段错误”并输出错误的数字(139)。
在过去的一个周末,我一直处于困境,尝试进行多次修复,但没有运气。如果有人可以指导我正确的方向,或者帮助我确定我的逻辑或语法错误,那就太好了。我将在下面发布代码,并在此先非常感谢您!
.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
解决方法
您的代码崩溃是因为您尝试读取/写入随机地址。根据公式128 +信号编号(SIGSEGV
是信号11),外壳程序会将崩溃转换为退出状态139。
通常,您不应该简单地选择一些随机地址并将数据存储在那里。这几乎总是崩溃,如果没有崩溃,那么该地址的内存仍然有可能被程序中的其他内容占用。
要解决此问题,应显式分配一些内存,并使用该内存区域的地址。最简单的方法是使用静态内存分配并将所需的数据放入.data
部分:
.section .data ; enter .data section
data: .int 0 ; first number
.int 1 ; second number
在这里,data
是一个符号。您可以给它指定任意名称,但其名称在源文件中必须唯一。然后,您可以在程序中加载data
的地址,而不用硬编码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
部分中指定内存的初始值。初始值始终是一系列零。