2

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

1 回答 1

3

您的代码崩溃是因为您尝试读取/写入随机地址。根据公式 128 + 信号编号(SIGSEGV即信号 11),您的 shell 会将此崩溃转换为退出状态 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。初始值将始终是一系列零。

于 2020-10-11T18:54:10.730 回答