0

I am trying to write a basic C program which calls an external assembly function on a Beaglebone white. The

As I understand it a segmentation error is when a program tries to access an illegal part of memory but I dont understand how that could happen since I followed an example which uses the same method.

Here is the main C program which calls the assembly function to multiply an inputted number by 5:

/*-- C_mult_by_5.c*/

#include <stdio.h>

extern int mult_by_5(int number);

int main()
    {
        int number_read;
        int number_read_by_5;
        printf("Hey, type a number");
        scanf("%d", &number_read);

        number_read_by_5 = mult_by_5(number_read);
        printf("%d times 5 is %d\n\r", number_read, number_read_by_5);

        return(0);
    }

Here is the assembly code used to carry out the operation:

/*-- mult_by_5.s*/

.data
.balign 4
return: .word 0

.balign 4
message : .asciz "Result: %d\n"

.text
.balign 4
.global printf
.global mult_by_5

mult_by_5:

ldr r1, address_of_return       /*r1 < address_of_return*/
str lr, [r1]                /* *r1 < lr*/

ldr r0, [r0]                    /*r0 < *r0*/

add r0, r0, r0, LSL #2          /*r0 < r0 + 4*r0*/
mov r1, r0                      /* r1 < r0 */

ldr r0, address_of_message      /*r0 < &message*/
bl printf                       /*call to printf*/

ldr lr, address_of_return       /*lr < &address_of_return*/
ldr lr, [lr]                /*lr < *lr*/
bx lr                   /*return from main using lr*/

address_of_return : .word return
address_of_message : .word message
.end

Has something happened to the link register during the running of the code that has made it try to return to an illegal address ?

  • 2
    Use GDB or some other debugger to single-step through, watching the registers. Note particularly what `ldr r0, [r0]` does, when r0 contains a number passed _by value_... – Notlikethat Mar 12 '16 at 15:45
  • Why store LR in a global var instead on the stack? And why is that global in the .text section, not .bss? Read and understand the ABI before messing with it. – too honest for this site Mar 12 '16 at 15:58

1 Answers1

0

Try,

/*-- mult_by_5.s*/

.text
.balign 4
.global printf
.global mult_by_5

mult_by_5:

add r1, r0, r0, LSL #2          /*r1 = r0 + 4*r0*/
ldr r0, =message                /*r0 < &message*/
b printf                        /*tail call printf */
message : .asciz "Result: %d\n"
.balign 4

.end

Also this question on ARM link and frame pointer might be helpful. Typically you can just push/pop the lr on the stack and not use .data or static memory. A stack data structure fits well with function calls so it is built into many machine languages.

Also, you can check what a compiler does.

Community
  • 1
  • 1
artless noise
  • 21,212
  • 6
  • 68
  • 105