- 呼び出し元のPCは、スタックのトップの保存しているみたい
> int funcb(int b) { return b; }
> int funca(int a) { int rc; rc = funcb(a); return rc; }
> main()
> {
> int rc = funca(123456789);
> return rc;
> }
------------------------------------------------
> ........
> funca:
> sts.l pr,@-r15 ! 呼び出し元のPCをスタックに保存
> mov.l r4,@r15 ! 引数の保存 @r15
> mov.l @r15,r4
> mov.l .L3,r1
> jsr @r1 ! prにpcを保存
> nop
> mov.l r0,@(4,r15) ! 戻り値の保存 @r15+4
> mov.l @(4,r15),r1
> mov r1,r0
> lds.l @r15+,pr ! 呼び出し元のPCをスタックから復元
> rts ! prの示すアドレスに復帰
> nop
> .L4: .align 2
> .L3: .long funcb
> ........
> .global main
> .type main, @function
> main:
> sts.l pr,@-r15
> mov.l .L6,r1
> mov r1,r4
> mov.l .L7,r1
> jsr @r1
> nop
> lds.l @r15+,pr
> rts
> nop
> .L8: .align 2
> .L6: .long 123456789
* SHのABIの調査
================
* 関数呼び出し前処理
> rc = func(1, 2, 3, 4, 5, 6, 7, 8, 9);
------------------------------------------------
> main:
> .........
> add #-20,r15 ! func()の引数用スタック確保 5配列:[5][6][7][8][9]
> mov r15,r2
> mov #5,r1
> mov.l r1,@r2 ! 引数5: r15 old r15 - 20
> mov #6,r1
> mov.l r1,@(4,r2) ! 引数6: r15 + 4 old r15 - 16
> mov #7,r1
> mov.l r1,@(8,r2) ! 引数7: r15 + 8 old r15 - 12
> mov #8,r1
> mov.l r1,@(12,r2) ! 引数8: r15 + 12 old r15 - 8
> mov #9,r1
> mov.l r1,@(16,r2) ! 引数9: r15 + 16 old r15 - 4
> mov #1,r4 ! 引数1: r4
> mov #2,r5 ! 引数2: r5
> mov #3,r6 ! 引数3: r6
> mov #4,r7 ! 引数4: r7
> mov.l .L9,r1
> jsr @r1
> nop
> add #20,r15 ! 引数用スタックの解放
> mov.l r0,@r15 ! 戻り値をスタックへ保存
> mov.l .L10,r1
> ........
* 関数呼び出し前のスタックの状態
> 0x4000014 old r15 - 0 ------ r15 + 20
> 引数5
> 0x4000010 old r15 - 4 ------ r15 + 16
> 引数6
> 0x400000c old r15 - 8 ------ r15 + 12
> 引数7
> 0x4000008 old r15 - 12 ------ r15 + 8
> 引数8
> 0x4000004 old r15 - 16 ------ r15 + 4
> 引数9
> 0x4000000 old r15 - 20 ------ r15 + 0
* 関数内部処理
> int func(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9)
> {
> int sum;
> sum = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
> return sum;
> }
------------------------------------------------
> func:
> add #-20,r15 ! 作業領域の確保: 5 配列を確保 [5][6][7][8][9]
> mov.l r4,@r15 ! 引数1
> mov.l r5,@(4,r15) ! 引数2
> mov.l r6,@(8,r15) ! 引数3
> mov.l r7,@(12,r15) ! 引数4
> mov.l @r15,r2 ! 引数1 -> r2
> mov.l @(4,r15),r1 ! 引数2 -> r1
> add r1,r2 ......
> mov.l @(8,r15),r1
> add r1,r2
> mov.l @(12,r15),r1
> add r1,r2
> mov.l @(20,r15),r1
> add r1,r2
> mov.l @(24,r15),r1
> add r1,r2
> mov.l @(28,r15),r1
> add r1,r2
> mov.l @(32,r15),r1
> add r1,r2
> mov.l @(36,r15),r1
> add r2,r1
> mov.l r1,@(16,r15)
> mov.l @(16,r15),r1
> mov r1,r0 ! r0: 合計
> add #20,r15 ! 作業領域の返却
> rts
> nop
* 関数呼出し後
> main:
> .........
> mov #3,r6 ! 引数3: r6
> mov #4,r7 ! 引数4: r7
> mov.l .L9,r1
> jsr @r1
> nop
> add #20,r15 ! func()の引数用スタックの解放
> mov.l r0,@r15 ! 戻り値をスタックへ保存
> mov.l .L10,r1
> ........