Follow the link in the assembly

I am trying to write a program to calculate the exponent of a number using the ARM-C interaction. I am using LPC1769 (cortex m3) for deduplication. Below 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 assembly code that 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 mov r9,lr ldr r4,[r0] ldr r2,[r1] loop: mul r4,r4 sub r2,#1 bne loop mov r0,r4 mov lr,r9 mov pc,lr label1: .word 0x02 label2: .word 0x03 

however, during a debugging session, I encounter a Hardfault error to execute "Exponentiatecore (m, n)".

as shown in the 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 doing some stack damage during alignment or is there an error in my interpretation? Please kindly help. early

+4
source share
2 answers

There are several problems in the code. Firstly, you have an infinite loop because your SUB command does not set flags. Change it to SUBS. The next problem is that you are manipulating the LR register unnecessarily. You do not call other functions from Exponentiatecore, so do not touch LR. The last function command must be "BX LR" to return to the calling program. Problem number 3 is that your multiplication command is incorrect. In addition to taking 3 parameters, if you multiply the number by yourself, it will grow too fast. For instance:

ExponentiateCore (10, 4);
Values ​​through each cycle:
R4 = 10, n = 4 - R4 = 100, n = 3
R4 = 10000, n = 2
R4 = 100,000,000 n = 1

Problem number 4 is that you change the non-volatile register (R4). If you do not save / restore them, you are allowed to delete R0-R3. Try instead:

 Start: stmfd sp!,{lr} ldr r0,=label1 ldr r1,=label2 bl Exponentiatecore // no need to call C again bl print ldmfd sp!,{pc} Exponentiatecore: // r0-&m, r1-&n ldr r0,[r0] mov r2,r0 ldr r1,[r1] cmp r1,#0 // special case for exponent value of 0 moveq r0,#1 moveq pc,lr // early exit loop: mul r0,r0,r2 // multiply the original value by itself n times subs r1,r1,#1 bne loop bx lr 
+3
source

I just add a start: push {r4-r11, lr} ... pop {r4-r11, pc}

Exponentiatecore: @ r0- & m, r1- & n push {r4-r11, lr} ... pop {r4-r11, pc}

and clear the print at the beginning and everything works fine

+1
source

All Articles