TCP/IPプロトコル・スタックの省メモリ開発事例(後編) ――ROM 8Kバイト,RAM 0.5KバイトにTCP/IPプロトコル・スタックを収める
●○● Column ●○●
◆やっぱりアセンブリ言語だね!◆
今回の開発では移植性を考慮して,C言語を用いて開発しています.しかし,マイコンのアーキテクチャや使用するCコンパイラにもよりますが,明らかにアセンブリ言語で記述したほうが高速に動作する処理もあります.どのような部分がそれにあたるのかを参考までに説明します.
● シフト演算はアセンブリ言語が向いている
今回,TCP/IPプロトコル・スタックの開発対象としたマイコンのうち,H8/Tiny以外はリトル・エンディアンでした.TCP/IPのデータはビッグ・エンディアン形式で格納されているため,リトル・エンディアンのマイコンを使用する場合,処理によっては,エンディアン変換,つまりバイト単位でデータをスワップ(バイト・スワップ)する必要があります.
バイト・スワップ処理は,16ビット長のデータを左に8ビット分シフトしたデータと,右に8ビット分シフトしたデータを作り,その論理和をとることで実現します(図A-1(a)).見かけは簡単ですが,シフト演算がけっこうくせものです.バレル・シフタ(演算回路)を持たないマイコンでは,シフト演算処理の実行に時間がかかってしまうのです(通常,シフトするビット数が多ければ多いほど時間がかかる).
今回使用した16ビット・マイコンの汎用レジスタは,16ビット長のレジスタのうち,上位8ビットと下位8ビットをそれぞれ別のレジスタとして使用できます.そこで,まずレジスタへのデータ転送を16ビット単位で行ってから,上位8ビットと下位8ビットのデータを,ほかのレジスタの下位8ビットと上位8ビットにそれぞれ転送することにより,シフト演算を使わずにバイト・スワップを実現しました(図A-1(b)).スワップの操作がレジスタ間のデータ転送になるので,少ない処理時間で実行できます.
● チェック・サムの計算もアセンブリ言語向き
チェック・サムの計算もアセンブリ言語で記述したほうが高速に処理できます.チェック・サムは,伝送データの和をとって算出します.TCPやIPの場合,伝送データをネットワーク・バイト・オーダ(ビッグ・エンディアン)の16ビットの数値として読み出していき,「1の補数和」の1の補数をチェック・サムとします.
1の補数和は,普通に足し算した結果のうちの最上位ビット(MSB:most significant bit)側のけたあふれ(繰り上がり)部分を最下位ビット(LSB:least significant bit)に加算することで計算できます(図A-2(a)).最上位ビットのけたあふれは,まとめて後から加算することができます.その加算時にけたあふれが発生したら,それもまた加算します(このあたりの詳細については,別途文献を参照していただきたい).したがって,チェック・サムの計算プログラムはリストA-1のように書けます.
このプログラムも,16ビット・マイコンにとっては問題があります.つまり,けたあふれを考慮すると変数sumは32ビット・データである必要があるため,全体的に32ビット演算となり,16ビット・マイコンで実行するには負担が大きくなります.
これを,キャリ付き加算命令を使って,加算でけたあふれが発生するたびに最下位ビットに加算していけば,変数sumは16ビット・データで十分です.つまり全体を16ビット演算にできます(図A-2(b)).