こんにちは。NoMaYです。e2 studio 7.5.0+RXスマートコンフィグレータplugin 7.5.0+GNURX 2019q2(4.8.4.201902)で作業していてスタック解析ビューの致命的な(だと私は思う)制限事項に気付きました。1箇所でも関数ポインタで関数呼び出しする箇所があると、以下の画面コピーの通り(原因が大変分かり難い)エラーになってしまうのですが、そもそもR_BSPモジュールにそういう箇所が存在していますので、実務的には全く使えない、ということになりますね。(ちなみに、FreeRTOS Kernelのソースにもそういう箇所が存在していますし、FITの各モジュールでのコールバック関数の呼び出しも関数ポインタを使用した関数呼び出しですね。)現象再現プロジェクトのファイル一式issue_20191007.zip 162KBe2 studioのスタック解析ビューはGNURXでは関数ポインタで関数呼び出ししているとエラーになる素朴に関数呼び出ししているのであればスタック解析ビューにスタック情報が表示される
NoMaY さんほや です。こんにちは。既知の問題として挙がっていますね。IDE-28579 : Stack Analysis doesn't work in the case of function pointershttps://www2.renesas.eu/_custom/software/ree_eclipse/e2studio7/docs/releasenotes/7.5.0/openissues.htm
ほや さん、こんにちは。NoMaYです。情報有難う御座います。このページをブラウザのお気に入りメニューに登録しないといけないですね、、、バグ内容「[GCCRX, GCCRL, GNU ARM Embedded] In a project that has function pointers, the Stack Analysis view cannot work correctly and not display information.」「[GCCRX, GCCRL, GNU ARM Embedded] (私の訳です)関数ポインタの使われているプロジェクトではスタック解析ビューは正しく動作せず情報を表示しません。」回避策「Add options to display stack information as warning message in Stack Analysis view to the specified files (except file has function pointers) which you want to see the stack size and rebuild, stack size information for functions in these files can display in Stack Analysis view.」「(意訳すると)関数ポインタの使われているソースを見つけてスタック情報を生成させないようにファイル単位でスタック情報生成オプションを外して下さい(付加しないようにして下さい)。(原文は、スタック情報を見たいファイル(ただし関数ポインタの使われていないソースであること)にだけスタック情報生成オプションを付加して下さい、かな。)」思うに、原文の方法では甚だ、私の意訳の方法でもやっぱり、必要スタックサイズを見積もりたいのだけれど、というニーズには厳しいかな、という気がしました。
こんにちは。NoMaYです。e2 studio v7.6.0がリリースされましたが、バグリストを見ると、修正されたようでした。(ちなみに、さっそくこのページもブラウザのお気に入りメニュー/ブックマークメニューに登録しました。)e²studio 7.6 Known Issues ListList generated on 02/10/2019 17:40:14www2.renesas.eu/_custom/software/ree_eclipse/e2studio7/docs/releasenotes/7.6.0/openissues.htm「IDE-28579Stack Analysis doesn't work in the case of function pointersStack Analysis View[GCCRX, GCCRL, GNU ARM Embedded] In a project that has function pointers, the Stack Analysis view cannot work correctly and not display information. [Workaround] Add options to display stack information as warning message in Stack Analysis view to the specified files (except file has function pointers) which you want to see the stack size and rebuild, stack size information for functions in these files can display in Stack Analysis view. This issue is fixed by e2 studio 7.6.」[思い付き]このページですが、e2 studioのヘルプメニューから開けるようになっていたら便利かも、、、[追記]オイオイwww「IDE-29941e2 GDB Server stopped working when setting EventpointsGDB server RXWhen you terminate a debug session after running it for a long time (more than 45 minutes), GDB server sometimes crash.」
こんにちは。NoMaYです。この不具合が修正されたというe2 studio v7.6.0を実際に動かしてみると、確かにGNURXでもスタック解析ビューにスタック情報が表示されるようになりました。ただ、以前に作成したCC-RX版FreeRTOSプロジェクトと現在手元で作成中のGNURX版FreeRTOSプロジェクトを較べると、違和感を感じるほどにスタックサイズが小さいです。もちろん、1つの理由としてすぐに思い浮かぶのが、今回、試しにnewlib-nanoのpre-buildを使ってビルドしたのですが、このライブラリの分は計上されていないと思います。もう1つは、予感として、引数や戻り番地の分が計上されていないかも知れない、という気がします。後日、調べてみようと思います。以下、画面コピーです。e2 studio v7.6.0でGNURXでもスタック解析ビューにスタック情報が表示されるようになった以前にCC-RXでスタック解析ビューにスタック情報を表示させた時はスタック使用量がもっと多かったのだが、、、
こんにちは。NoMaYです。別スレッド『GNURX用のCCRXmachine.hとCCRXmachine.cというソースがe2 studioフォルダにありました(内容は概ね名前から予想される通りのものでした)』に投稿したのですが、先月リリースされたGNURX 8.3.0.202002(及びGNURL78 4.9.2.202002)でスタック使用量の計算方法の修正があったようなので調べてみました。調査に使ったプロジェクトのファイル一式issue_20200509.zip 742KB上記に含まれるビルド結果のフォルダ一覧HardwareDebug.8.3.0.201904.O0 → GNURX 8.3.0.201904 最適化無し (-O0)HardwareDebug.8.3.0.201904.O2 → GNURX 8.3.0.201904 最適化レベル2 (-O2)HardwareDebug.8.3.0.201904.Og → GNURX 8.3.0.201904 デバッグ優先最適化 (-Og)HardwareDebug.8.3.0.202002.O0 → GNURX 8.3.0.202002 最適化無し (-O0)HardwareDebug.8.3.0.202002.O2 → GNURX 8.3.0.202002 最適化レベル2 (-O2)HardwareDebug.8.3.0.202002.Og → GNURX 8.3.0.202002 デバッグ優先最適化 (-Og)結果は以下の表の通り、かなり期待値と一致するようになっていました。ただ、まだ以下の不一致が残っていました。また、一致していても疑念のある項目もあります。GNURX 8.3.0.202002で残っているスタック使用量の不一致の内容(1) 最適化ありの場合に通常の関数で表示値が期待値より4バイト多い (表の赤色文字/ピンク色背景の箇所)(2) 割り込み関数でPSWの分を計上し忘れている気がします (表の赤色文字/黄色背景の箇所)GNURX 8.3.0.202002でスタック使用量が一致していても疑念のある内容(ただし直感でしかないですが)(3) 最適化ありの場合に通常の関数で基本的に表示値が期待値より4バイト多いが別要因発生により運良く一致? (表の青色文字/ピンク色背景の箇所)(4) 割り込み関数では基本的にPSWの分を計上し忘れているが別要因発生により運良く一致? (表の青色文字/黄色背景の箇所)
スタック解析ビューの表示は以下の画面コピーの通り、[呼び出し先関数との合計を表示]に設定しています。また、期待値はリストファイルのアセンブラコードから求めたものです。以下、それぞれのスタック解析ビューの画面コピーです。GNURX 8.3.0.201904 最適化無し (-O0)GNURX 8.3.0.201904 最適化レベル2 (-O2)GNURX 8.3.0.201904 デバッグ優先最適化 (-Og)GNURX 8.3.0.202002 最適化無し (-O0)GNURX 8.3.0.202002 最適化レベル2 (-O2)GNURX 8.3.0.202002 デバッグ優先最適化 (-Og)以下、ソースコード(抜粋)と幾つかのリストファイル(抜粋)です。src/Test.c
uint32_t func0( void ){ return 0;}uint32_t func1( uint32_t a1 ){ return a1;}uint32_t func4( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4 ){ return a1 + a2 + a3 + a4;}uint32_t func5( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5 ){ return a1 + a2 + a3 + a4 + a5;}uint32_t func8( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8 ){ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;}
src/TestStackAnalysisForGNURX.c
extern volatile uint32_t a1, a2, a3, a4, a5, a6, a7, a8;extern volatile uint32_t r0, r1, r4, r5, r8;
int main(void){ r0 = func0(); r1 = func1( a1 ); r4 = func4( a1, a2, a3, a4 ); r5 = func5( a1, a2, a3, a4, a5 ); r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 );#if 1 (*fptr)();#elif 0 func();#endif while(1) { // TODO: add application code here } return 0;}
generate/interrupt_handlers.h
void INT_Excep_PERIB_INTB181(void) __attribute__ ((interrupt));
generate/inthandler.c
void INT_Excep_PERIB_INTB181(void){ }
HardwareDebug.8.3.0.202002.O2/Test.lst
7 _func0: 12:../src/Test.c **** uint32_t func0( void ) 13:../src/Test.c **** { 14:../src/Test.c **** return 0; 15:../src/Test.c **** } 13 0000 66 01 mov.L #0, r1 14 0002 02 rts ⇒ スタック使用量の期待値 = 4
20 _func1: 17:../src/Test.c **** uint32_t func1( uint32_t a1 ) 18:../src/Test.c **** { 19:../src/Test.c **** return a1; 20:../src/Test.c **** } 26 0000 02 rts ⇒ スタック使用量の期待値 = 4
32 _func4: 22:../src/Test.c **** uint32_t func4( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4 ) 23:../src/Test.c **** { 24:../src/Test.c **** return a1 + a2 + a3 + a4; 38 0000 4B 34 add r3, r4 40 0002 4B 24 add r2, r4 25:../src/Test.c **** } 42 0004 4B 41 add r4, r1 44 0006 02 rts ⇒ スタック使用量の期待値 = 4
50 _func5: 27:../src/Test.c **** uint32_t func5( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5 ) 28:../src/Test.c **** { 54 0000 60 40 sub #4, r0 29:../src/Test.c **** return a1 + a2 + a3 + a4 + a5; 58 0002 06 89 04 02 add 8[r0].L, r4 60 0006 4B 34 add r3, r4 61 0008 4B 24 add r2, r4 30:../src/Test.c **** } 63 000a 4B 41 add r4, r1 65 000c 67 01 rtsd #4 ⇒ スタック使用量の期待値 = 8
71 _func8: 32:../src/Test.c **** uint32_t func8( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8 ) 33:../src/Test.c **** { 75 0000 7E A7 push.l r7 77 0002 71 00 F0 add #-16, r0 34:../src/Test.c **** return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8; 81 0005 75 47 18 mov.L #24, r7 82 0008 4B 07 add r0, r7 83 000a A8 F5 mov.L 8[r7], r5 85 000c 06 89 75 03 add 12[r7].L, r5 86 0010 06 89 75 01 add 4[r7].L, r5 87 0014 06 88 75 add [r7].L, r5 88 0017 4B 45 add r4, r5 89 0019 4B 35 add r3, r5 90 001b 4B 25 add r2, r5 35:../src/Test.c **** } 92 001d 4B 51 add r5, r1 94 001f 3F 77 05 rtsd #20, r7-r7 ⇒ スタック使用量の期待値 = 24
HardwareDebug.8.3.0.202002.O2/inthandler.lst
1370 _INT_Excep_PERIB_INTB181: 1372 ; Note: Interrupt Handler 1373 0000 7F 95 rte ⇒ スタック使用量の期待値 = 8
HardwareDebug.8.3.0.202002.O2/TestStackAnalysisForGNURX.lst
18 _main: 55:../src/TestStackAnalysisForGNURX.c **** int main(void) 56:../src/TestStackAnalysisForGNURX.c **** { 21 0000 6E 6C pushm r6-r12 ↓ 23 0002 71 00 F0 add #-16, r0 ⇒ main()内のスタック使用量の期待値 = 48 = 4(戻り番地分)+28(r6~r12)+16(此処) 57:../src/TestStackAnalysisForGNURX.c **** 58:../src/TestStackAnalysisForGNURX.c **** r0 = func0(); 59:../src/TestStackAnalysisForGNURX.c **** r1 = func1( a1 ); 27 0005 FB 72 00 00 00 00 mov.L #_a1, r7 58:../src/TestStackAnalysisForGNURX.c **** r1 = func1( a1 ); 29 000b 05 00 00 00 bsr _func0 58:../src/TestStackAnalysisForGNURX.c **** r1 = func1( a1 ); 32 000f FB A2 00 00 00 00 mov.L #_r0, r10 33 0015 E3 A1 mov.L r1, [r10] 60:../src/TestStackAnalysisForGNURX.c **** r4 = func4( a1, a2, a3, a4 ); 36 0017 FB B2 00 00 00 00 mov.L #_a2, r11 59:../src/TestStackAnalysisForGNURX.c **** r1 = func1( a1 ); 38 001d EC 71 mov.L [r7], r1 40 001f FB 62 00 00 00 00 mov.L #_a3, r6 41 0025 FB A2 00 00 00 00 mov.L #_a4, r10 61:../src/TestStackAnalysisForGNURX.c **** r5 = func5( a1, a2, a3, a4, a5 ); 43 002b FB C2 00 00 00 00 mov.L #_a5, r12 59:../src/TestStackAnalysisForGNURX.c **** r4 = func4( a1, a2, a3, a4 ); 45 0031 05 00 00 00 bsr _func1 59:../src/TestStackAnalysisForGNURX.c **** r4 = func4( a1, a2, a3, a4 ); 48 0035 FB 52 00 00 00 00 mov.L #_r1, r5 49 003b E3 51 mov.L r1, [r5] 60:../src/TestStackAnalysisForGNURX.c **** r4 = func4( a1, a2, a3, a4 ); 52 003d EC 71 mov.L [r7], r1 53 003f EC B2 mov.L [r11], r2 54 0041 EC 63 mov.L [r6], r3 55 0043 EC A4 mov.L [r10], r4 56 0045 05 00 00 00 bsr _func4 60:../src/TestStackAnalysisForGNURX.c **** r4 = func4( a1, a2, a3, a4 ); 59 0049 FB 52 00 00 00 00 mov.L #_r4, r5 60 004f E3 51 mov.L r1, [r5] 63 0051 EC 71 mov.L [r7], r1 64 0053 EC B2 mov.L [r11], r2 65 0055 EC 63 mov.L [r6], r3 66 0057 EC A4 mov.L [r10], r4 67 0059 EC C5 mov.L [r12], r5 68 005b E3 05 mov.L r5, [r0] 69 005d 05 00 00 00 bsr _func5 72 0061 FB 52 00 00 00 00 mov.L #_r5, r5 73 0067 E3 51 mov.L r1, [r5] 62:../src/TestStackAnalysisForGNURX.c **** r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 ); 76 0069 EC 71 mov.L [r7], r1 77 006b EC B2 mov.L [r11], r2 78 006d EC 63 mov.L [r6], r3 79 006f EC A4 mov.L [r10], r4 80 0071 EC C6 mov.L [r12], r6 81 0073 FB 72 00 00 00 00 mov.L #_a6, r7 82 0079 EC 75 mov.L [r7], r5 83 007b FB 72 00 00 00 00 mov.L #_a7, r7 84 0081 EC 77 mov.L [r7], r7 85 0083 FB A2 00 00 00 00 mov.L #_a8, r10 86 0089 EC AA mov.L [r10], r10 87 008b E3 06 mov.L r6, [r0] 88 008d A0 0D mov.L r5, 4[r0] 89 008f E7 0A 03 mov.L r10, 12[r0] 90 0092 A0 87 mov.L r7, 8[r0] 91 0094 05 00 00 00 bsr _func8 63:../src/TestStackAnalysisForGNURX.c **** #if 1 64:../src/TestStackAnalysisForGNURX.c **** (*fptr)(); 94 0098 FB 72 00 00 00 00 mov.L #_fptr, r7 95 009e EC 77 mov.L [r7], r7 62:../src/TestStackAnalysisForGNURX.c **** r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 ); 97 00a0 FB A2 00 00 00 00 mov.L #_r8, r10 98 00a6 E3 A1 mov.L r1, [r10] 101 00a8 7F 17 jsr r7 103 .balign 8,3,3 104 .L4: 65:../src/TestStackAnalysisForGNURX.c **** #elif 0 66:../src/TestStackAnalysisForGNURX.c **** func(); 67:../src/TestStackAnalysisForGNURX.c **** #endif 68:../src/TestStackAnalysisForGNURX.c **** 69:../src/TestStackAnalysisForGNURX.c **** while(1) 70:../src/TestStackAnalysisForGNURX.c **** { 71:../src/TestStackAnalysisForGNURX.c **** // TODO: add application code here 72:../src/TestStackAnalysisForGNURX.c **** } 109 00aa 2E 00 bra .L4
こんにちは。NoMaYです。今度はCC-RXでスタック使用量の見積もりの表示が期待値と一致するかどうか先日のGNURXと同様に調べてみました。結果は以下の表の通り、問題は見つかりませんでした。なお、今回気付いたのですが、CC-RXでは、GNURX(及びCC-RL)と異なり、スタック使用量の計算方法に以下の相違点がありました。(なお、諸般の事情で、CC-RXはV2.03、CC-RLはV1.02、です。) プログラムが必要とするスタック領域サイズを見積もるという観点からは、CC-RXの方法がGNURX(及びCC-RL)の方法より誤差が少なくなるので望ましいと思います。(誤差の具体例が、CC-RLですが、別スレッド『RL78 FreeRTOS APIを特別なおまじない記述無しで割り込みルーチンから呼び出せるようにしてみた(CC-RL/GNURL78)』にあります。)CC-RXとGNURX(及びCC-RL)のスタック使用量の計算方法の相違(CC-RXの方法がGNURX(及びCC-RL)の方法より望ましい)CC-RXの場合:スタック渡し引数で使用されるスタックは呼び出し先の関数に計上されるGNURX(及びCC-RL)の場合:スタック渡し引数で使用されるスタックは呼び出し元の関数に計上される調査に使ったプロジェクトのファイル一式issue_20200515.zip 987KB上記に含まれるビルド結果のフォルダ一覧DefaultBuild.v203.optimize0.speed → CC-RX V2.03 最適化レベル0/実行性能重視 (-optimize=0 -speed)DefaultBuild.v203.optimize2.speed → CC-RX V2.03 最適化レベル最大/実行性能重視 (-optimize=max -speed)
スタック解析ビューの表示は以下の画面コピーの通り、[呼び出し先関数との合計を表示]に設定しています。また、期待値はリストファイルのアセンブラコードから求めたものです。以下、それぞれのスタック解析ビューの画面コピーです。CC-RX V2.03 最適化レベル0/実行性能重視 (-optimize=0 -speed)CC-RX V2.03 最適化レベル最大/実行性能重視 (-optimize=max -speed)以下、幾つかのリストファイル(抜粋)です。DefaultBuild.v203.optimize_0.speed/src/Test.lst
00000000 _func0: ; 12 uint32_t func0( void )00000000 6040 SUB #04H, R0 ; 13 { ; 14 return 0;00000002 F80600 MOV.L #00000000H, [R0]00000005 6601 MOV.L #00000000H, R1 ; 15 }0000007 6701 RTSD #04H ⇒ スタック使用量の期待値 = 8 = 4(戻り番地分)+04H
00000009 _func1: .STACK _func1=12 ; 17 uint32_t func1( uint32_t a1 )00000009 6080 SUB #08H, R00000000B A009 MOV.L R1, 04H[R0] ; 18 { ; 19 return a1;0000000D E301 MOV.L R1, [R0] ; 20 }0000000F 6702 RTSD #08H ⇒ スタック使用量の期待値 = 12 = 4(戻り番地分)+08H
00000011 _func4: .STACK _func4=24 ; 22 uint32_t func4( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4 )00000011 7100EC ADD #0FFFFFFECH, R000000014 A101 MOV.L R1, 10H[R0]00000016 A08A MOV.L R2, 0CH[R0]00000018 A083 MOV.L R3, 08H[R0]0000001A A00C MOV.L R4, 04H[R0] ; 23 { ; 24 return a1 + a2 + a3 + a4;0000001C A901 MOV.L 10H[R0], R10000001E 06890103 ADD 0CH[R0].L, R100000022 06890102 ADD 08H[R0].L, R100000026 4B41 ADD R4, R100000028 E301 MOV.L R1, [R0] ; 25 }0000002A 6705 RTSD #14H ⇒ スタック使用量の期待値 = 24 = 4(戻り番地分)+14H
0000002C _func5: .STACK _func5=28 ; 27 uint32_t func5( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5 )0000002C 7100E8 ADD #0FFFFFFE8H, R00000002F A109 MOV.L R1, 14H[R0]00000031 A102 MOV.L R2, 10H[R0]00000033 A08B MOV.L R3, 0CH[R0]00000035 A084 MOV.L R4, 08H[R0]00000037 A98A MOV.L 1CH[R0], R2 ← スタック渡し引数00000039 A00A MOV.L R2, 04H[R0] ; 28 { ; 29 return a1 + a2 + a3 + a4 + a5;0000003B A909 MOV.L 14H[R0], R10000003D 06890104 ADD 10H[R0].L, R100000041 06890103 ADD 0CH[R0].L, R100000045 06890102 ADD 08H[R0].L, R100000049 4B21 ADD R2, R10000004B E301 MOV.L R1, [R0] ; 30 }0000004D 6706 RTSD #18H ⇒ スタック使用量の期待値 = 32 = 4(スタック渡し引数分)+4(戻り番地分)+18H
0000004F _func8: .STACK _func8=40 ; 32 uint32_t func8( uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8 )0000004F 7100DC ADD #0FFFFFFDCH, R000000052 A201 MOV.L R1, 20H[R0]00000054 A18A MOV.L R2, 1CH[R0]00000056 A183 MOV.L R3, 18H[R0]00000058 A10C MOV.L R4, 14H[R0]0000005A E5000A04 MOV.L 28H[R0], 10H[R0] ← スタック渡し引数0000005E E5000B03 MOV.L 2CH[R0], 0CH[R0] ← スタック渡し引数00000062 E5000C02 MOV.L 30H[R0], 08H[R0] ← スタック渡し引数00000066 AB0A MOV.L 34H[R0], R2 ← スタック渡し引数00000068 A00A MOV.L R2, 04H[R0] ; 33 { ; 34 return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;0000006A AA01 MOV.L 20H[R0], R10000006C 06890107 ADD 1CH[R0].L, R100000070 06890106 ADD 18H[R0].L, R100000074 06890105 ADD 14H[R0].L, R100000078 06890104 ADD 10H[R0].L, R10000007C 06890103 ADD 0CH[R0].L, R100000080 06890102 ADD 08H[R0].L, R100000084 4B21 ADD R2, R100000086 E301 MOV.L R1, [R0] ; 35 }00000088 6709 RTSD #24H ⇒ スタック使用量の期待値 = 56 = 16(スタック渡し引数分)+4(戻り番地分)+24H
DefaultBuild.v203.optimize_0.speed/generate/intprg.lst
00000168 _Excep_PERIA_INTA209: .STACK _Excep_PERIA_INTA209=8 .RVECTOR 209,_Excep_PERIA_INTA209 ; 558 ; 559 // PERIA INTA209 ; 560 void Excep_PERIA_INTA209(void){ }00000168 7F95 RTE ⇒ スタック使用量の期待値 = 8
DefaultBuild.v203.optimize_0.speed/src/TestStackAnalysisForCCRX.lst
00000001 _main: .STACK _main=24 ; 41 int main(void)00000001 7EA6 PUSH.L R6 ⇒ main()内のスタック使用量の期待値 = 8 = 4(戻り番地分)+4(此処) ; 42 { ; 44 r0 = func0();00000003 05rrrrrr A BSR _func000000007 FBE2rrrrrrrr MOV.L #_r0, R140000000D E3E1 MOV.L R1, [R14] ; 45 r1 = func1( a1 );0000000F FBE2rrrrrrrr MOV.L #_a1, R1400000015 ECE1 MOV.L [R14], R100000017 05rrrrrr A BSR _func10000001B FBE2rrrrrrrr MOV.L #_r1, R1400000021 E3E1 MOV.L R1, [R14] ; 46 r4 = func4( a1, a2, a3, a4 );00000023 FBE2rrrrrrrr MOV.L #_a1, R1400000029 ECE1 MOV.L [R14], R10000002B FBE2rrrrrrrr MOV.L #_a2, R1400000031 ECE2 MOV.L [R14], R200000033 FBE2rrrrrrrr MOV.L #_a3, R1400000039 ECE3 MOV.L [R14], R30000003B FBE2rrrrrrrr MOV.L #_a4, R1400000041 ECE4 MOV.L [R14], R400000043 05rrrrrr A BSR _func400000047 FBE2rrrrrrrr MOV.L #_r4, R140000004D E3E1 MOV.L R1, [R14] ; 47 r5 = func5( a1, a2, a3, a4, a5 );0000004F FBE2rrrrrrrr MOV.L #_a1, R1400000055 ECE1 MOV.L [R14], R100000057 FBE2rrrrrrrr MOV.L #_a2, R140000005D ECE2 MOV.L [R14], R20000005F FBE2rrrrrrrr MOV.L #_a3, R1400000065 ECE3 MOV.L [R14], R300000067 FBE2rrrrrrrr MOV.L #_a4, R140000006D ECE4 MOV.L [R14], R40000006F FBE2rrrrrrrr MOV.L #_a5, R1400000075 ECEE MOV.L [R14], R1400000077 6040 SUB #04H, R000000079 E30E MOV.L R14, [R0]0000007B 05rrrrrr A BSR _func50000007F 6240 ADD #04H, R000000081 FBE2rrrrrrrr MOV.L #_r5, R1400000087 E3E1 MOV.L R1, [R14] ; 48 r8 = func8( a1, a2, a3, a4, a5, a6, a7, a8 );00000089 FBE2rrrrrrrr MOV.L #_a1, R140000008F ECE1 MOV.L [R14], R100000091 FBE2rrrrrrrr MOV.L #_a2, R1400000097 ECE2 MOV.L [R14], R200000099 FBE2rrrrrrrr MOV.L #_a3, R140000009F ECE3 MOV.L [R14], R3000000A1 FBE2rrrrrrrr MOV.L #_a4, R14000000A7 ECE4 MOV.L [R14], R4000000A9 FBE2rrrrrrrr MOV.L #_a5, R14000000AF ECEE MOV.L [R14], R14000000B1 FBF2rrrrrrrr MOV.L #_a6, R15000000B7 ECF5 MOV.L [R15], R5000000B9 FBF2rrrrrrrr MOV.L #_a7, R15000000BF ECFF MOV.L [R15], R15000000C1 FB62rrrrrrrr MOV.L #_a8, R6000000C7 EC66 MOV.L [R6], R6000000C9 7100F0 ADD #0FFFFFFF0H, R0000000CC A08E MOV.L R6, 0CH[R0]000000CE E70F02 MOV.L R15, 08H[R0]000000D1 A00D MOV.L R5, 04H[R0]000000D3 E30E MOV.L R14, [R0]000000D5 05rrrrrr A BSR _func8000000D9 710010 ADD #10H, R0000000DC FBE2rrrrrrrr MOV.L #_r8, R14000000E2 E3E1 MOV.L R1, [R14] ; 49 #if 1 ; 50 (*fptr)();000000E4 FBE2rrrrrrrr MOV.L #_fptr, R14000000EA ECEE MOV.L [R14], R14000000EC 7F1E JSR R14000000EE L17: ; bb24 ; 51 #elif 0 ; 52 func(); ; 53 #endif ; 54 ; 55 while(1)000000EE 2Err B BRA L17 ; 56 { ; 57 // TODO: add application code here ; 58 } ; 59 }