前回はstrcmpの例を見てきた。今回はstrchrの話。
strchrは検索文字として ‘\0′ が渡される場合があるので、注意。
通常は 文字が見つからずに末端の0に至った場合は NULLを返すが、’\0’ を検索していたときはそのアドレスを返す必要がある。
char *strchr(const char *s,int c) { while (*s && (*s!=c)) { s++; } return (*s==c)? s: NULL; }
アセンブラで素直に書いてみる
探したい文字はAccBに入っているものとする。前回同様に ループ末で分岐、tstは使わない形で書いてある。
dex loop: inx cmpb 0,x beq found ldaa 0,x bne loop : found:
インデックスアドレッシングは遅い
MC6800のインデックスアドレッシングは遅いのである(5〜7 cyc)。上記コードでは2回使われていて、ループ内部は 4+5+4+5+4 = 22cyc かかる。
比較と0テストで2回インデックスアドレッシングを使っているのを 1回に減らしてみよう。ロードは減らせないので比較を変更する。
4+5+2+4+2+4 = 21cyc である。ldaaで0かどうかはわかるのに、tstを実行しているのが いかにも無駄である。
dex loop: inx ldaa 0,x cba beq found tsta bne loop : found:
終了時に判別する
順序を入れ替えて、先に文字列末かどうかを判定する。
0を見つけたときに、見つけたい文字が0だったかを再確認するように変更。
4+5+4+2+4 = 19cyc になった。
(文字が見つかっても見つからなくても)6cyc余計に必要だが、ループあたり3cyc減っているので、2文字以上あれば元は取れる。
dex loop: inx ldaa 0,x beq break cba bne loop found: : break: cba beq found :

コメント