XC8アセンブラ理解/引数の表現
引数が1つの場合
code:example.c
uint8_t div_uint8_value(uint8_t a) {
return a >> 1;
}
これをコンパイルした結果、次のようなアセンブリコードとなった。
code:xc8compiler-test.X.production.lst
1794 ;psect for function _div_uint8_value
1795 07DD _div_uint8_value:
1796
1797 ;incstack = 0
1799 ;div_uint8_value@a stored from wreg
1800 07DD 00F0 movwf div_uint8_value@a
1801
1802 ;main.c: 10: return a >> 1;
1803 07DE 3670 lsrf div_uint8_value@a,w
1804 07DF 0008 return
1805 07E0 __end_of_div_uint8_value:
ちょっと見づらいので、アセンブリ命令がある行だけ抜き出し、動作をコメントしてみる
code:xc8compiler-test.X.production.lst
1795 07DD _div_uint8_value:
1800 07DD 00F0 movwf div_uint8_value@a # a = W
1803 07DE 3670 lsrf div_uint8_value@a,w # W = a >> 1
1804 07DF 0008 return
1805 07E0 __end_of_div_uint8_value:
この関数を利用する側のコードも見てみる
code:xc8compiler-test.X.production.lst
1692 ;main.c: 14: LATA = div_uint8_value(LATA);
1693
1694 ;incstack = 0
1696 07E9 0816 movf 22,w ;volatile
1697 07EA 3187 27DD 3187 fcall _div_uint8_value
1698 07ED 0096 movwf 22 ;volatile
多分22がLATAのアドレス。
第一引数がWレジスタに乗ってくる。
戻り値はWレジスタで返す。
引数が2つの場合
code:example.c
uint8_t add_uint8_values(uint8_t a, uint8_t b) {
return a + b;
}
これをコンパイルした結果、次のようなアセンブリコードとなった(アセンブリ命令がある行だけ抜き出し)。
code:xc8compiler-test.X.production.lst
1841 07E0 _add_uint8_values:
1846 07E0 00F1 movwf add_uint8_values@a
1849 07E1 0871 movf add_uint8_values@a,w
1850 07E2 0770 addwf add_uint8_values@b,w
1851 07E3 0008 return
1852 07E4 __end_of_add_uint8_values:
最初の2行はなんで存在するの?無くても問題なくない?
最適化レベルを3にしても、add_uint8_valuesのコンパイル結果は全く変わらなかった。
利用側のコード
code:xc8compiler-test.X.production.lst
1700 ;main.c: 15: LATB = add_uint8_values(2, 9);
1701 07EE 3009 movlw 9 # W = 9
1702 07EF 00F2 movwf ??_main # *0x72 = W
1703 07F0 0872 movf ??_main,w # W = *0x72
1704 07F1 00F0 movwf add_uint8_values@b # b = W
1705 07F2 3002 movlw 2
1706 07F3 3187 27E0 3187 fcall _add_uint8_values
1707 07F6 0097 movwf 23 ;volatile
第一引数と戻り値は、1引数の関数と変わらず、Wレジスタに乗る。
第二引数はファイルレジスタに乗る。
最終的に9をbに書いているわけだが、回りくどい……
movwf ??_mainとmovf ??_main,wは不要では?
最適化レベル3でも最適化されないのか?なぜ?
a, bはファイルレジスタ上に割り当てられている。
code:aとbの定義.lst
1620 0070 add_uint8_values@b:
1625 0070 ds 1
1627 0071 add_uint8_values@a:
1632 0071 ds 1