1

このプログラムは、アセンブリでの参照渡しに関する以前の問題を簡単に修正したものです。これは指数、すなわち 2^2 を計算します ここにプログラムがあります--

#include<stdio.h>
#include<stdlib.h>
extern int Start_func (void);
extern int Exponentiatecore(int m,int n);
void print(int i);
int Exponentiate(int m,int n);

int main()
{
printf("in main func\n");
Start_func();
return 0;
}


int Exponentiate(int m,int n)
{
printf("in exponentiate func\n");

    if(n==0)
     return 1;
    else
    {
        int result=0;
        result=Exponentiatecore(m,n);    
        printf("calculation done\n");
        printf("result=%d\n",result);
        return (result);
    }

}


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

これを補完するアセンブリ コードは次のとおりです。

Start_func:
    mov r5,lr
            mov r0,#2
    mov r1,#2
    bl Exponentiate
    bl print
    mov lr,r5
    bx lr

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

           mov r2,r0
       loop:
           mul r2,r0
           subs r1,#1
           bne loop
           mov r0,r2
           bx lr

これが分解です---

      Start_func:
00000270:   mov r5, lr
00000272:   mov.w r0, #2
00000276:   mov.w r1, #2
0000027a:   bl 0x2bc <Exponentiate>   //branch to exponentiate function
0000027e:   bl 0x31c <print>
00000282:   mov lr, r5
00000284:   bx lr 
      Exponentiatecore:
00000286:   mov r2, r0
      loop:
00000288:   mul.w r2, r0, r2
0000028c:   subs r1, #1
0000028e:   bne.n 0x288 <loop>
00000290:   mov r0, r2
00000292:   bx lr 


      main:
0000029c:   push {r7, lr}
0000029e:   add r7, sp, #0
000002a0:   movw r3, #11300 ; 0x2c24
000002a4:   movt r3, #0
000002a8:   mov r0, r3
000002aa:   bl 0xdbc <printf>
000002ae:   bl 0x270 <Start_func>
000002b2:   mov.w r3, #0
000002b6:   mov r0, r3
000002b8:   pop {r7, pc}
000002ba:   nop 
      Exponentiate:
000002bc:   push {r7, lr}
000002be:   sub sp, #16 
000002c0:   add r7, sp, #0
000002c2:   str r0, [r7, #4]
000002c4:   str r1, [r7, #0]
000002c6:   movw r3, #11316 ; 0x2c34
000002ca:   movt r3, #0 
000002ce:   mov r0, r3
000002d0:   bl 0xdbc <printf>
000002d4:   ldr r3, [r7, #0]
000002d6:   cmp r3, #0
000002d8:   bne.n 0x2e0 <Exponentiate+36>
000002da:   mov.w r3, #1
000002de:   b.n 0x312 <Exponentiate+86>
000002e0:   mov.w r3, #0
000002e4:   str r3, [r7, #12]
000002e6:   ldr r0, [r7, #4]
000002e8:   ldr r1, [r7, #0]
000002ea:   blx 0x284 <Start_func+20>      //this jump should be at 0x286
000002ee:   mov r3, r0
000002f0:   str r3, [r7, #12]
000002f2:   movw r3, #11340 ; 0x2c4c
000002f6:   movt r3, #0
000002fa:   mov r0, r3

命令のデバッグ中にハード フォールト エラーが発生する -->

result=Exponentiatecore(m,n);

code_red による NXP LPC Xpresso IDE で LPC 1769(Embedded Artists) を使用しています。

この行を見ると --> 000002ea: blx 0x284

Exponentiatecore() 関数が開始する 0x286 にジャンプする必要がありますが、残念ながらジャンプはその 1 つ上の命令です。

上記のコードのどこが間違っているのか、誰でも教えてください。前もって感謝します。

4

1 に答える 1