(57)【要約】      （修正有）【課題】ＲＸＣコンパイラが用意する文字列操作をおこなう標準ライブラリ関数strncatに対して、直接に文字列操作命令であるSMOVUを当てはめて、strncat関数のオブジェクトサイズを増やすことなく、実行サイクル数を大幅に削減する。【解決手段】演算処理装置が、連結先アドレスR1、連結元アドレスR2、及び、連結する文字サイズR3を入力データとし、連結先アドレスR1に文字サイズR3を加算することにより、転送後の末尾のアドレスR4を得るとともに、前記文字サイズR3に１を加算し、転送後の末尾のアドレスR4、連結元アドレスR2、及び、１を加算された文字サイズを入力データとして、文字列転送命令を実行し、実行後、１を加算された文字サイズ分全て転送できたか否かを判断し、全て転送できた場合に転送後の末尾の文字に'\0'を上書きする。【選択図】図６Ａ
2012208869.tif 000002
【特許請求の範囲】
【請求項１】
文字列転送命令を使用して標準ライブラリ関数である文字列連結関数の動作を演算処理装置により行う方法であって、演算処理装置が、
記憶領域における文字列の連結先アドレス(R1)、記憶領域における連結元アドレス(R2)、及び、連結する文字サイズ(R3)を入力データとするステップと、
前記連結先アドレス(R1)に文字サイズ(R3)を加算することにより、転送後の末尾のアドレス(R4)を得るステップと、
前記文字サイズ(R3) に１を加算することにより、１を加算された文字サイズを得るステップと、
前記転送後の末尾のアドレス(R4)、前記連結元アドレス(R2)、及び、前記１を加算された文字サイズ（R3＋1）を入力データとして、文字列転送命令を実行するステップと、
実行後、前記１を加算された文字サイズ分全て転送できたか否かを判断するステップと、
全て転送できた場合に転送後の末尾の文字に '\0' を上書きするステップと、を有することを特徴とする
文字列転送命令を用いて文字列連結関数の動作を行う方法。
【請求項２】
請求項１において、全て転送できた場合に転送後の末尾の文字に '\0' を上書きするステップに替えて、実行後の転送する文字サイズ（R3）の値を判定して、ゼロ以外であれば、'\0' を上書きしないステップを有することを特徴とする文字列転送命令を用いて文字列連結関数の動作を行う方法。
【請求項３】
文字列転送命令を使用して標準ライブラリ関数である文字列連結関数の動作を演算処理装置に行わせるプログラムであって、演算処理装置に、
記憶領域における文字列の連結先アドレス(R1)、記憶領域における連結元アドレス(R2)、及び、連結する文字サイズ(R3)を入力データとする機能と、
前記連結先アドレス(R1)に文字サイズ(R3)を加算することにより、転送後の末尾のアドレス(R4)を得る機能と、
前記文字サイズ(R3) に１を加算することにより、１を加算された文字サイズを得る機能と、
前記転送後の末尾のアドレス(R4)、前記連結元アドレス(R2)、及び、前記１を加算された文字サイズ（R3＋1）を入力データとして、文字列転送命令を実行する機能と、
実行後、前記１を加算された文字サイズ分全て転送できたか否かを判断する機能と、
全て転送できた場合に転送後の末尾の文字に '\0' を上書きする機能と、を実現させることを特徴とする
文字列転送命令を用いて文字列連結関数の動作を行うプログラム。
【請求項４】
請求項３において、全て転送できた場合に転送後の末尾の文字に '\0' を上書きする機能に替えて、実行後の転送する文字サイズ（R3）の値を判定して、ゼロ以外であれば、'\0' を上書きしない機能を実現させることを特徴とする文字列転送命令を用いて文字列連結関数の動作を行うプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ＲＸファミリＣＰＵの命令セットを最大限に利用して、標準ライブラリ関数の中で文字列連結を行う関数の動作を実現するプログラムに関する。
【背景技術】
【０００２】
ルネサステクノロジ製のＲＸファミリＲＸ６００シリーズＣＰＵ向けに開発されたＣ／Ｃ＋＋コンパイラでは、ユーザ向けに標準ライブラリ関数を用意している。しかし、この標準ライブラリ関数のソースは、Ｃ／Ｃ＋＋言語で記述されており、ＲＸファミリＣＰＵの命令セットを十分に利用したプログラムとなっていないものがある。
【０００３】
文字列処理方法の先行技術としては、特許文献１がある。
【先行技術文献】
【特許文献】
【０００４】
【特許文献１】特許第２８２６９２７号公報
【発明の概要】
【発明が解決しようとする課題】
【０００５】
ＲＸファミリＲＸ６００シリーズＣＰＵ命令セットでは、文字列操作に特化した命令、すなわち文字列操作命令が用意されている。
しかし、このＲＸファミリＣＰＵの文字列操作命令は、ＲＸファミリＲＸ６００シリーズ向けＣ／Ｃ＋＋コンパイラ（以降、ＲＸＣコンパイラと呼ぶ）により、Ｃ／Ｃ＋＋言語で記述されたソースをコンパイルした場合には、生成されない。これは、文字列操作命令の動作が複雑で、Ｃ／Ｃ＋＋言語に直接当てはめることができないためである。
【０００６】
本発明の目的は、ＲＸＣコンパイラが用意する標準ライブラリ関数のうち文字列連結を行うstrncat関数に対して、文字列操作命令であるSMOVU命令を直接当てはめてstrncat関数の動作を実現し、strncat関数のオブジェクトサイズを増やすことなく、実行サイクル数を大幅に削減するプログラムを提供することにある。
【課題を解決するための手段】
【０００７】
上記目的を達成するために、本発明は、以下の構成を提供する。
本発明の第１の態様は、文字列転送命令を使用して標準ライブラリ関数である文字列連結関数の動作を演算処理装置により行う方法であって、演算処理装置が、記憶領域における文字列の連結先アドレス(R1)、記憶領域における連結元アドレス(R2)、及び、連結する文字サイズ(R3)を入力データとするステップと、前記連結先アドレス(R1)に文字サイズ(R3)を加算することにより、転送後の末尾のアドレス(R4)を得るステップと、前記文字サイズ(R3) に１を加算することにより、１を加算された文字サイズを得るステップと、前記転送後の末尾のアドレス(R4)、前記連結元アドレス(R2)、及び、前記１を加算された文字サイズ（R3＋1）を入力データとして、文字列転送命令を実行するステップと、実行後、前記１を加算された文字サイズ分全て転送できたか否かを判断するステップと、全て転送できた場合に転送後の末尾の文字に '\0' を上書きするステップと、を有することを特徴とする。
【０００８】
上記において、全て転送できた場合に転送後の末尾の文字に '\0' を上書きするステップに替えて、実行後の転送する文字サイズ（R3）の値を判定して、ゼロ以外であれば、'\0' を上書きしないステップを有することが、好適である。
【０００９】
本発明の第２の態様は、文字列転送命令を使用して標準ライブラリ関数である文字列連結関数の動作を演算処理装置に行わせるプログラムであって、演算処理装置に、記憶領域における文字列の連結先アドレス(R1)、記憶領域における連結元アドレス(R2)、及び、連結する文字サイズ(R3)を入力データとする機能と、前記連結先アドレス(R1)に文字サイズ(R3)を加算することにより、転送後の末尾のアドレス(R4)を得る機能と、前記文字サイズ(R3) に１を加算することにより、１を加算された文字サイズを得る機能と、前記転送後の末尾のアドレス(R4)、前記連結元アドレス(R2)、及び、前記１を加算された文字サイズ（R3＋1）を入力データとして、文字列転送命令を実行する機能と、実行後、前記１を加算された文字サイズ分全て転送できたか否かを判断する機能と、全て転送できた場合に転送後の末尾の文字に '\0' を上書きする機能と、を実現させることを特徴とする。
【００１０】
上記において、全て転送できた場合に転送後の末尾の文字に '\0' を上書きする機能に替えて、実行後の転送する文字サイズ（R3）の値を判定して、ゼロ以外であれば、'\0' を上書きしない機能を実現させることが、好適である。
【発明の効果】
【００１１】
ＲＸファミリＲＸ６００シリーズＣＰＵ命令セットの文字列操作命令を用いてＲＸＣコンパイラにおける標準ライブラリ関数であるstrncat関数の動作を実現する本発明の方法及びプログラムには、次のような効果がある。
連結する文字数を１文字分増やすことで、連結後の余分なメモリアクセスを発生させない。また、連結した文字に '\0' が含まれるかを判断するコストを不要とする。
この結果、strncat関数のオブジェクトサイズは、実行速度優先の場合に、使用前の ６９バイトに対して、使用後には、３７バイトに縮小できる。
加えて、実行速度数は、使用前と比較して、１００文字を連結する場合、約１２％（８分の１）に短縮できる。
【図面の簡単な説明】
【００１２】
【図１Ａ】標準ライブラリ関数のうち、文字列連結を行なうstrncat関数の動作を示したフローチャートである。
【図１Ｂ】図１Ａのフローチャートに相当するstrncat関数の動作をＣ言語で示した図である。
【図２】strncat関数をＲＸファミリＣＰＵ命令で示した図である。
【図３】ＲＸファミリＣＰＵの文字列操作命令であるSMOVUの動作を示したフローチャートである。
【図４】strncat関数を、SMOVU命令を使用して実現した場合を示した図である。
【図５Ａ】strncat関数の仕様に合わない場合のプログラム例を示した図である。（ａ）はstrncat関数の正しい動作、（ｂ）はSMOVU命令を使用した場合の間違った動作、（ｃ）はSMOVU命令を使用した場合の正しい動作をそれぞれ示している。
【図５Ｂ】（ａ）はstrncat関数の正しい動作、（ｂ）はSMOVU命令を使用した場合の正しい動作をそれぞれ示している。
【図５Ｃ】（ａ）はstrncat関数の正しい動作、（ｂ）はSMOVU命令を使用した場合の正しい動作をそれぞれ示している。
【図６Ａ】本発明により、strncat関数の仕様に合わせて、SMOVU命令を使用した場合の動作を示したフローチャートである。
【図６Ｂ】本発明により、strncat関数を、SMOVU命令を使用して実現した場合を示した図である。
【発明を実施するための形態】
【００１３】
本発明は、ＲＸＣコンパイラが用意する標準ライブラリ関数のうち文字列連結を行う文字列連結関数であるstrncat関数に対して、文字列操作命令を直接当てはめることによりstrncat関数の動作を実現する方法及びプログラムであり、演算処理装置により実行される。文字列操作命令として、文字列転送命令であるSMOVU命令を用いる。
【００１４】
本発明の実施形態を説明するに先立って、文字列連結を行うstrncat関数の動作（図１Ａ、図１Ｂ、図２）及び文字列転送命令であるSMOVU命令の動作（図３、図４）を説明する。
【００１５】
図１Ａは、標準ライブラリ関数のうち、文字列連結を行なうstrncat関数の動作を示したフローチャートである。strncat関数は、記憶領域における連結先アドレス p、記憶領域における連結元アドレス S2、及び、連結する（すなわち転送する）文字サイズ（バイト数）N を入力データ(引数)とする（ステップ１１）。そして、連結先アドレス p の文字列の終端に、連結元アドレス S2 の文字列を、N（N＞０）を上限の文字サイズとして連結する動作を行う。
【００１６】
先ず、連結する連結元アドレス S2 の文字サイズが０より大きいか否かを判断する（ステップ１２）。文字サイズが０の場合は、連結先アドレス p の終端に '\0' を付加する（*p＝'\0'）（ステップ１３）。ステップ１２において、文字サイズが０より大きい場合は、連結する文字列が '\0' であるか否かを判断する（ステップ１４）。連結する文字列が '\0' の場合は、連結先アドレスpの終端に '\0' を付加する（*p＝'\0'）（ステップ１３）。ステップ１４において、連結する文字列が '\0' でない場合は、連結先アドレスpに連結元アドレスから１文字転送する（ステップ１５）。続いて、連結先アドレスを更新し（p++）、連結元アドレスを更新し（S2++）、文字サイズNを１つ減らす（N--）。その後、ステップ１２に戻り、処理を繰り返す。こうして得られるstrncat関数の返却値は、連結先アドレスpの値となる。
【００１７】
図１Ｂは、図１Ａのフローチャートに相当するstrncat関数の動作をＣ言語のソースで示した図である。
【００１８】
本発明では、strncat関数の動作を実現するために、図１ＢのＣ言語で示したソースから作成される命令は使用せずに、文字列操作命令のうち文字列検索命令である SUNTIL.B命令、及び、文字列転送命令であるSMOVU命令 を使用する。なお、図１ＢのＣ言語のソースでは、連結先アドレスpの文字列の終端を指すために、S1 の文字列長として標準ライブラリ関数 strlen を使用しているが、これにも文字列操作命令を使用する。
【００１９】
図２は、strncat関数をＲＸファミリＣＰＵ命令で示した図である。
図２では、文字列を連結するために、連結する文字サイズ分だけ、文字転送を繰り返している。そのため、繰り返しのために分岐する命令の実行コストが、文字サイズ分だけ必要となる。また、もし、分岐をさせずに、文字転送のみを連続実行させた場合には、転送する回数分だけ、命令のサイズが増えることとなる。
【００２０】
図３は、ＲＸファミリＣＰＵの文字列操作命令であるSMOVU命令の動作を示したフローチャートである。SMOVU命令は、記憶領域における文字列の連結先アドレスR1 、記憶領域における連結元アドレスR2、及び、連結する（転送する）文字サイズ R3 を入力データとする（ステップ３１）。そして、R2 を転送元アドレスとして、R1 の転送先アドレスに、 '\0'  が検出されるまで、R3 を上限の転送サイズ（バイト数）として、アドレス加算方向に文字列転送を行なう。ただし、命令実行後のR1, R2 の値は不定となる。
【００２１】
先ず、連結する連結元アドレス R2 の文字サイズが０より大きいか否かを判断する（ステップ３２）。文字サイズが０の場合は、処理を終える。ステップ３２において、文字サイズが０より大きい場合は、連結先アドレス R1 に連結元アドレスから１文字転送する（ステップ３３）。続いて、連結先アドレス R1 を更新し（R1++）、連結元アドレス R2 を更新し（R2++）、文字サイズR3を１つ減らす（R3--）（ステップ３４）。次に、連結した文字が '\0' であるか否かを判断する（ステップ３５）。文字が '\0' である場合は、処理を終える。ステップ３５において文字が '\0' でない場合は、ステップ３２に戻り、処理を繰り返す。
【００２２】
本発明では、strncat関数の動作を実現するために、文字列の連結処理においてこの SMOVU 命令を使用する。
【００２３】
図４は、strncat関数を、SMOVU命令を使用して実現した場合を示した図である。各行の処理を順に説明する。
・SUNTIL.B 命令で検索する文字( '\0' )のデータとして、連結元アドレスR2 にゼロをMOV.L命令で代入する。
・SUNTIL.B 命令で検索する回数の上限として、文字サイズR3 に最大値である 0xffffffff を代入する。
・SUNTIL.B 命令で '\0' を検索した後は、連結先アドレスR1 に '\0' の次のアドレスが設定される。
・'\0' のアドレスを、転送開始位置にするため、SUB命令で 連結先アドレスR1 に設定されたアドレス値を減算する。
・転送後に、連結した文字列の末尾を '\0' とするために、ADD命令で、転送開始位置＋連結文字数を加算して、そのアドレスを保持しておく。
・SMOVU で連結元の文字列を、指定された文字数（R3）分転送する。あるいは、'\0' まで転送する。
・SMOVU 実行後の 文字サイズR3 の値が ゼロであれば、指定された文字数（R3）分を全て転送できたので、文字列の末尾の位置に '\0' を MOV.B命令で代入する。
【００２４】
ただし、図４の方法では、strncat関数の仕様と食い違いが発生してしまう。
【００２５】
図５Ａは、strncat関数の仕様に合わない場合のプログラム例を示した図である。
図５Ａは、strncat（S1,"123\0",4）のstrncat関数を実行する場合の例である。（ａ）はstrncat関数の正しい動作、（ｂ）はSMOVU命令を使用した場合の間違った動作をそれぞれ示している。
【００２６】
このプログラムを実行した正しい動作結果では、（ａ）に示すように連結後の文字列は "ABC123\0"となるべきだが、実際には（ｂ）に示すようにSMOVU命令をそのまま使用した場合の間違った動作結果では、連結後の文字列が"ABC123\0\0" と連結部分の文字列の末尾に余分な '\0' が付加されてしまう。これは、SUNTIL.B命令が、転送文字数の最後の文字（４文字目）として転送した '\0' を、転送文字数に含めてしまうのが原因である。SUNTIL.B命令は、その動作の仕様として、最後に転送する文字が、'\0' の場合と、'\0' 以外の場合との区別をしていない。そのため、SUNTIL.B命令の実行後に、最後に転送した文字が '\0' か否かを判断して、'\0' であれば、末尾に '\0' を付加しないようにする必要がある。
【００２７】
しかし、最後に転送した文字を判断するためには、そのアドレスを計算する命令と、アドレスを代入するレジスタ、計算したアドレスから値をロードする命令が必要となり、その分のコストが増えてしまう。
【００２８】
これを踏まえて、strncat関数の仕様に合わせて、SMOVU命令の使用方法を変更する。
図５Ａの（ｃ）、図５Ｂの（ｂ）及び図５Ｃの（ｂ）は、変更されたSMOVU命令の使用方法に基づく正しい動作結果を示した図である。図５Ｂ及び図５Ｃの（ａ）はstrncat関数の正しい動作である。なお、図５Ｂは、strncat（S1,"123\0",3）のstrncat関数を実行する場合の例であり、図５Ｃは、strncat（S1,"1234\0",3）のstrncat関数を実行する場合の例である。
【００２９】
図６Ａは、strncat関数の仕様に合わせて、SMOVU命令を使用した場合の動作を示したフローチャートである。
図３と同様に、記憶領域における文字列の連結先アドレスR1 、記憶領域における連結元アドレスR2、及び、連結する（転送する）文字サイズ R3 を入力データとする。
【００３０】
先ず、転送後の末尾となるアドレスを求めるために、連結先アドレスに文字サイズを加算する（R4＝R1＋R3）（ステップ６１）。次に、文字サイズ R3 に１を加算する（R3＝R3＋1）（ステップ６３）。その後、図３と同様にSMOVU命令を実行する（ステップ６４）。実行後、SMOVU命令により文字サイズ分全て転送できたか否かを判断する（ステップ６５）。文字サイズ分全て転送できた場合は、転送後の末尾の文字に '\0' を上書きする（*R4＝ '\0' ）（ステップ６６）。文字サイズ分全て転送できなかった場合は、処理を終える。
【００３１】
図６Ｂは、図６Ａのフローチャートに相当し、strncat関数を、SMOVU命令を使用して実現した場合を示した図である。
【００３２】
SMOVU命令の動作では、転送する文字が '\0' か否かを判断する前に転送をするため、最後に転送した文字が '\0' 以外であったか否かを判断できない。そこで、'\0' 以外だった場合には、もう１文字を転送するように、転送する文字サイズに１を加算する。これにより、転送する文字サイズ分を全て転送できた場合には、本来の文字サイズ（加算前の値）の終端は、必ず '\0' 以外となる。この時、余分に１文字多く転送してしまっているが、この位置は、本来 '\0' を付加する位置なので、転送後に、'\0' を上書き（ストア）すればよいことになる（図５Ｃ（ｂ）参照）。
【００３３】
もし、余分に転送した１文字が '\0' の場合であっても、'\0' を上書き（ストア）するだけである（図５Ｂ（ｂ）参照）。転送する文字列の途中に '\0' があった場合には、SMOVU命令の実行後の転送する文字サイズR3 の値を判定して、ゼロ以外であれば、'\0' を上書き（ストア）しなければよい（図５Ａ（ｃ）参照）。
【００３４】
このように、SMOVU命令により、余分に１文字多く転送をしてしまうが、結果は strncat関数と同じにすることが可能である。
【００３５】
本発明によるSMOVU命令を使用してstrncat関数の動作を正しく実現する方法をまとめると次の通りとなる。
（i）SMOVU命令で転送する文字サイズの文字数を１文字増やす（指定された文字数よりも１文字多く転送する）。
（ii）SMOVU命令実行後の、残文字数がゼロであれば（文字数分を全て転送できた場合）、転送後の文字列の終端文字を '\0' で上書きする。残文字数がゼロ以外であれば、転送する文字の途中に '\0' があったことを示す（ '\0' まで転送した）ことを示すので、 '\0' で上書きはしない。
【図１Ａ】
2012208869.tif 000003
【図１Ｂ】
2012208869.tif 000004
【図２】
2012208869.tif 000005
【図３】
2012208869.tif 000006
【図４】
2012208869.tif 000007
【図５Ａ】
2012208869.tif 000008
【図５Ｂ】
2012208869.tif 000009
【図５Ｃ】
2012208869.tif 000010
【図６Ａ】
2012208869.tif 000011
【図６Ｂ】
2012208869.tif 000012