pass by reference in arm assembly

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

pass by reference in arm assembly

1,078 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by venkateshkuppan on Thu Mar 21 01:33:02 MST 2013
I am trying to write a program to calculate the exponential of a number using ARM-C inter-working. I am using LPC1769(cortex m3) for debuuging.

The following is the code:

/*here is the main.c file*/

#include<stdio.h>
#include<stdlib.h>
extern int Start (void);
extern int Exponentiatecore(int *m,int *n);
void print(int i);
int Exponentiate(int *m,int *n);
int main()
{
Start();
return 0;
}


int Exponentiate(int *m,int *n)
{
    if (*n==0)
        return 1;
    else
    {
        int result;
        result=Exponentiatecore(m,n);
        return (result);
    }

}

void print(int i)
{
printf("value=%d\n",i);
}



this is the assembly code which complements the above C code




.syntax unified
        .cpu cortex-m3
        .thumb
        .align
        .global Start
        .global Exponentiatecore
        .thumb
        .thumb_func

Start:
    mov r10,lr
    ldr r0,=label1
    ldr r1,=label2
    bl Exponentiate
    bl print
    mov lr,r10
    mov pc,lr

Exponentiatecore:    // r0-&m, r1-&n

ldr r4,[r0]
ldr r2,[r1]
loop:
mul r4,r4
sub r2,#1
bne loop
mov r0,r4
mov pc,lr

label1:
.word 0x02


label2:
.word 0x03




however during the debug session, I encounter a Hardfault error for the execution of "Exponentiatecore(m,n)".

as seen in debug window.

Name : HardFault_Handler
Details:{void (void)} 0x21c <HardFault_Handler>
Default:{void (void)} 0x21c <HardFault_Handler>
Decimal:<error reading variable>
Hex:<error reading variable>
Binary:<error reading variable>
Octal:<error reading variable>



Am I making some stack corruption during alignment or is there a mistake in my interpretation? please kindly help. thankyou in advance
0 Kudos
4 Replies

736 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by venkateshkuppan on Thu Mar 21 13:08:05 MST 2013
Thanks a lot wrighflyer. It's indeed a great way to attack the problem. :D
The program works fine till the execution of this line
"result = Exponentiatecore(m,n);". I think I am corrupting either the value of link register(lr) or Stack pointer(SP). This might be occurring due to the multiple switching the program does from C to assembly and assembly to C.
Here is a description.....
#1 from C --> #2 assembly(Start routine) -->#3 C function (exponentiate) -->#4 assembly (Exponentiatecore) --> accordingly the rewind :)  

is this the exact problem? any solutions on how I can prevent it? thanks in advance
0 Kudos

736 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wrighflyer on Thu Mar 21 08:47:51 MST 2013
What I meant was something like this:
__attribute__((noinline)) int Exponentiatecore(int *m,int *n) {
    *m = *m * *n;
}

int m,n;

int main (void)
{
    m = 37; n = 56;
    Exponentiatecore(&m, &n);

when compiled the C compiler generated:
    .section    .text.Exponentiatecore,"ax",%progbits
    .align    2
    .global    Exponentiatecore
    .thumb
    .thumb_func
    .type    Exponentiatecore, %function
Exponentiatecore:
.LFB178:
    .file 1 "../src/main.c"
    .loc 1 21 0
    .cfi_startproc
    @ args = 0, pretend = 0, frame = 0
    @ frame_needed = 0, uses_anonymous_args = 0
    @ link register save eliminated.
.LVL0:
    .loc 1 22 0
    ldr    r3, [r0, #0]
    ldr    r2, [r1, #0]
    mul    r3, r2, r3
    str    r3, [r0, #0]
.LVL1:
    .loc 1 23 0
    bx    lr
    .cfi_endproc
.LFE178:
    .size    Exponentiatecore, .-Exponentiatecore

So clearly &m and &n are passed in r0 and r1 (which is the EABI). You can now just replace this C compiler generated code with your own solution between .LVL0: and .LFE178: and it should just work.
0 Kudos

736 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by frame on Thu Mar 21 08:11:13 MST 2013

Quote:
Why not simply write a stub version of Exponentiatecore() in C, compile  with -save-temps and then use the .s file as the basis of what you want  to do?



I agree.
Whereby, I believe any decent compiler will keep up with your asm coding capabilities, or even beat you ...[IMG]http://knowledgebase.nxp.com/images/icons/icon7.gif[/IMG]
0 Kudos

736 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wrighflyer on Thu Mar 21 02:28:36 MST 2013
Why not simply write a stub version of Exponentiatecore() in C, compile with -save-temps and then use the .s file as the basis of what you want to do?
0 Kudos