学校の課題でH8/300のアセンブリを読まされたお話(その1 関数呼び出しとレジスタについて)。

学校では、(時代遅れなのではないかと感じる)H8/300というマイコンボードを使ってアセンブリの勉強をします。

相変わらずクソなので、少しまとめておこうかなと。。。

何もしないmain関数

まず、はじめに、このようなソースコード(main.c)をアセンブリにしたいとおもいます。

#include "h8-3052-iodef.h"

void main(void) {}

h8-3052-iodef.hとかいうやつはとりあえず知りません。僕は興味がありません。

$ h8300-hms-gcc -S -I . -o main.s main.c

そして、このmain.sを開いてみると、

;   GCC For the Hitachi H8/300
;  By Hitachi America Ltd and Cygnus Support


    .file "main.c"
    .section .text
    .align 1
    .global _main
_main:
    mov.w  r6,@-r7
    mov.w  r7,r6
    mov.w  @r7+,r6
    rts
    .end
    .ident    "GCC: (GNU) 3.3.6"

これだけ見て、すべてを悟れる人間がいれば強い人なので、わざわざこれを読むことないと思うのですがね。

関数呼び出しだけがあるmain関数

次は、こんなソースコードアセンブリにします。

#include "h8-3052-iodef.h"

void test(void) {}

void main(void) {
    test();
}

そうすると、以下のようなアセンブリを出力します。

;   GCC For the Hitachi H8/300
;  By Hitachi America Ltd and Cygnus Support


    .file "main.c"
    .section .text
    .align 1
    .global _test
_test:
    mov.w  r6,@-r7
    mov.w  r7,r6
    mov.w  @r7+,r6
    rts
    .align 1
    .global _main
_main:
    mov.w  r6,@-r7
    mov.w  r7,r6
    jsr  @_test
    mov.w  @r7+,r6
    rts
    .end
    .ident    "GCC: (GNU) 3.3.6"

はい、この2つの差分だけを見て、すべてを悟れる人間はそれなりに強いはずです。

H8/300の仕様

察せる人でないと、アセンブリを読もうとは思わないとは思いますが、H8/300では、r6がベースポインタで、r7がスタックポインタになります。

つまり、

    mov.w   r6,@-r7
    mov.w  r7,r6

が、関数の最初に行われる命令群で、

    mov.w   @r7+,r6
    rts

が、関数の最後に行われる命令群になります。

そして、

    jsr   @_test

が、関数呼び出しになります。