Assembly 需要帮助找出ARM中的分段错误吗

Assembly 需要帮助找出ARM中的分段错误吗,assembly,x86,arm,machine-language,Assembly,X86,Arm,Machine Language,所以我最近收到了一个二年级计算机科学模块的项目,我们在那里学习计算机架构。我们被指示编写ARM汇编代码,以输出n=15和n=30的斐波那契序列 我曾尝试在线查看多个资源,但ARM的使用范围已不再广泛,2020年也不再受支持。我已经能够编译和运行我的代码,但是它告诉我“分段错误”,并输出错误的数字(139) 上周末我一直被困在那里,尝试了多次修复,但运气不佳。如果有人能指导我正确的方向,或者帮助我识别我的逻辑或语法错误,那就太好了。我将在下面发布代码,并提前感谢您 .global main .f

所以我最近收到了一个二年级计算机科学模块的项目,我们在那里学习计算机架构。我们被指示编写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

您的代码崩溃是因为您尝试读取/写入随机地址。此崩溃由shell根据公式128+信号编号(
SIGSEGV
is signal 11)转换为退出状态139

您通常不应该简单地选择一些随机地址并将数据存储在那里。这几乎总是会崩溃,如果没有崩溃,那么该地址的内存仍有可能被程序中的其他东西使用

要解决此问题,您应该显式分配一些内存,并使用该内存区域的地址。最简单的方法是使用静态内存分配,并将所需数据放入
。data
部分:

        .section .data    ; enter .data section
data:   .int 0            ; first number
        .int 1            ; second number
这里,
数据
是一个符号。您可以给它任何您想要的名称,但它的名称在源文件中必须是唯一的。然后,您可以在程序中加载
数据的地址,而不是硬编码
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
部分中指定内存的初始值。初始值始终是一系列零。

您是否尝试使用调试器查找分段错误发生的位置?如果是,在哪里?EMU8086仅适用于8086。它不会运行ARM程序。PuTTY不是模拟器。这是一个与其他系统建立终端连接的程序,它不会为您运行任何ARM程序。你到底用什么运行这个程序?你如何组装和连接它?我需要知道所有这些,这样我才能理解到底是什么问题。好的,谢谢你的澄清。由于整个流感大流行,这所大学被迫关门。因此,我们使用vpn连接到大学的网络,然后使用putty和一个特殊生成的IP连接到大学计算机实验室中设置的几个rasberry pi。然后我们一直在使用putty命令,比如as-o等,gcc-o等,./name echo;$?为了编译,运行等。希望这有助于澄清给定的情况,再次感谢您的帮助和努力!那个视频太糟糕了。。。请不要试图跟踪像那样随机的Youtube视频。这只会让你困惑。不管怎么说,我现在正在写一个答案。但是ARM在2020年不再得到广泛的应用,也不再得到支持了——你可以追溯到:ARM似乎正在接管世界,包括苹果即将推出的台式机/笔记本电脑。(虽然这将是64位ARM,也称为AArch64。)您不需要像x86那样的无数好的或坏的教程,您只需要一些好的。ARM的供应商文档不像x86那么容易获取,但是有很多很好的ARM信息。e、 该网站的其他部分都很棒。也许youtube视频会少一些,但那又怎样?非常感谢你的投入!但是我其余的逻辑和语法正确吗?我会跳到我的编辑器上,尝试应用这些技巧,如果我仍在努力,很可能会与您联系,或者如果我成功,则将此标记为已回答。再次感谢,希望您能享受余下的一天。@KryptonZA阅读代码了解它的功能。看起来它试图在内存中生成一个斐波那契数数组。它似乎没有返回任何东西。我建议您尝试自己想出一些逻辑来解决这个练习,而不是复制您不理解的代码。首先用伪代码绘制逻辑,然后将每个位转换为指令。尽可能使用寄存器,而不是内存作为变量。好吧,但就像我说的,我只有一个40页的pdf,它只包含基本的操作,所以我仍然在尝试如何输出寄存器的内容,以便能够评估算法的正确性。这只是本模块为期两周的最后一次练习,我们只得到了pdf。所以我并没有像java那样花上几个小时,尤其是看到它只有两周,而且再也没有被使用过。我不能只使用寄存器,而不使用内存吗?或者这会使事情变得太复杂吗?@KryptonZA我明白了。您应该能够使用just寄存器很好地解决此练习。要将值作为退出状态返回操作系统,请将其置于
r0
中,然后再返回
main
函数。您还可以通过调用libc中的
printf
函数来打印数字。好的,太棒了,谢谢您的提示。但是如果我只使用寄存器,因为我们只需要返回值,这与我目前正在做的有什么不同呢。因为直到我明白