KryptonZA
KryptonZA

Reputation: 33

Need help figuring out a segmentation fault in ARM

so I recently received a project for a 2nd year computer science module, where we did computer architecture. We were instructed to write ARM Assembly code to output the fibonacci sequence for n=15 as well as n=30.

I have tried checking out multiple resources online, but ARM is not as widely used, nor supported in 2020 anymore. I have been able to compile and run my code, however it tells me "segmentation fault" and outputs the wrong number (139).

I have been stuck for the past weekend, attempting multiple fixes, with no luck. If anyone could just guide me in the right direction, or help me identify my logical or syntax error, it would be great. I will post the code below, and thank you so much in advance!!!

.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

Upvotes: 3

Views: 1720

Answers (1)

fuz
fuz

Reputation: 92984

Your code crashes because you try to read/write a random address. This crash is translated by your shell into exit status 139 according to the formula 128 + signal number (SIGSEGV is signal 11).

You should generally not simply pick some random address and store your data there. This almost always crashes and if it does not, it's still likely that the memory at that address is used by something else in your program.

To fix this issue, you should allocate some memory explicitly and use the address of that memory region. The easiest way to do so is to use static memory allocation and place the data you need in the .data section:

        .section .data    ; enter .data section
data:   .int 0            ; first number
        .int 1            ; second number

Here, data is a symbol. You can give it whatever name you want, but its name must be unique in the source file. You can then load the address of data in your program instead of hard-coding 0x50000000:

        ldr r5, =data     ; load the address of data

Note that if you want to place code in the file after defining your variables, you need to switch back to the .text section. Code (i.e. program text) always goes into the .text section.

        .section .text    ; switch back to the .text section

At the beginning of the file, the current section is implicitly the .text section, but it's generally a good idea to always switch sections explicitly before emitting any sort of code or data.

It is also possible to place uninitialised data in the .bss section. This is especially useful if you want to allocate an array of data and don't want to type out that many .int directives.

        .section .bss     ; enter .bss section
data:   .space 8          ; reserve 8 bytes of memory

Contrary to the .data section, it is not possibly to specify initial values for memory in the .bss section. The initial value will always be a series of zeroes.

Upvotes: 4

Related Questions