説明

文字列転送命令を用いて文字列連結関数の動作を行う方法及びプログラム

【課題】RXCコンパイラが用意する文字列操作をおこなう標準ライブラリ関数strncatに対して、直接に文字列操作命令であるSMOVUを当てはめて、strncat関数のオブジェクトサイズを増やすことなく、実行サイクル数を大幅に削減する。
【解決手段】演算処理装置が、連結先アドレスR1、連結元アドレスR2、及び、連結する文字サイズR3を入力データとし、連結先アドレスR1に文字サイズR3を加算することにより、転送後の末尾のアドレスR4を得るとともに、前記文字サイズR3に1を加算し、転送後の末尾のアドレスR4、連結元アドレスR2、及び、1を加算された文字サイズを入力データとして、文字列転送命令を実行し、実行後、1を加算された文字サイズ分全て転送できたか否かを判断し、全て転送できた場合に転送後の末尾の文字に'\0'を上書きする。

【発明の詳細な説明】
【技術分野】
【0001】
本発明は、RXファミリCPUの命令セットを最大限に利用して、標準ライブラリ関数の中で文字列連結を行う関数の動作を実現するプログラムに関する。
【背景技術】
【0002】
ルネサステクノロジ製のRXファミリRX600シリーズCPU向けに開発されたC/C++コンパイラでは、ユーザ向けに標準ライブラリ関数を用意している。しかし、この標準ライブラリ関数のソースは、C/C++言語で記述されており、RXファミリCPUの命令セットを十分に利用したプログラムとなっていないものがある。
【0003】
文字列処理方法の先行技術としては、特許文献1がある。
【先行技術文献】
【特許文献】
【0004】
【特許文献1】特許第2826927号公報
【発明の概要】
【発明が解決しようとする課題】
【0005】
RXファミリRX600シリーズCPU命令セットでは、文字列操作に特化した命令、すなわち文字列操作命令が用意されている。
しかし、このRXファミリCPUの文字列操作命令は、RXファミリRX600シリーズ向けC/C++コンパイラ(以降、RXCコンパイラと呼ぶ)により、C/C++言語で記述されたソースをコンパイルした場合には、生成されない。これは、文字列操作命令の動作が複雑で、C/C++言語に直接当てはめることができないためである。
【0006】
本発明の目的は、RXCコンパイラが用意する標準ライブラリ関数のうち文字列連結を行うstrncat関数に対して、文字列操作命令であるSMOVU命令を直接当てはめてstrncat関数の動作を実現し、strncat関数のオブジェクトサイズを増やすことなく、実行サイクル数を大幅に削減するプログラムを提供することにある。
【課題を解決するための手段】
【0007】
上記目的を達成するために、本発明は、以下の構成を提供する。
本発明の第1の態様は、文字列転送命令を使用して標準ライブラリ関数である文字列連結関数の動作を演算処理装置により行う方法であって、演算処理装置が、記憶領域における文字列の連結先アドレス(R1)、記憶領域における連結元アドレス(R2)、及び、連結する文字サイズ(R3)を入力データとするステップと、前記連結先アドレス(R1)に文字サイズ(R3)を加算することにより、転送後の末尾のアドレス(R4)を得るステップと、前記文字サイズ(R3) に1を加算することにより、1を加算された文字サイズを得るステップと、前記転送後の末尾のアドレス(R4)、前記連結元アドレス(R2)、及び、前記1を加算された文字サイズ(R3+1)を入力データとして、文字列転送命令を実行するステップと、実行後、前記1を加算された文字サイズ分全て転送できたか否かを判断するステップと、全て転送できた場合に転送後の末尾の文字に '\0' を上書きするステップと、を有することを特徴とする。
【0008】
上記において、全て転送できた場合に転送後の末尾の文字に '\0' を上書きするステップに替えて、実行後の転送する文字サイズ(R3)の値を判定して、ゼロ以外であれば、'\0' を上書きしないステップを有することが、好適である。
【0009】
本発明の第2の態様は、文字列転送命令を使用して標準ライブラリ関数である文字列連結関数の動作を演算処理装置に行わせるプログラムであって、演算処理装置に、記憶領域における文字列の連結先アドレス(R1)、記憶領域における連結元アドレス(R2)、及び、連結する文字サイズ(R3)を入力データとする機能と、前記連結先アドレス(R1)に文字サイズ(R3)を加算することにより、転送後の末尾のアドレス(R4)を得る機能と、前記文字サイズ(R3) に1を加算することにより、1を加算された文字サイズを得る機能と、前記転送後の末尾のアドレス(R4)、前記連結元アドレス(R2)、及び、前記1を加算された文字サイズ(R3+1)を入力データとして、文字列転送命令を実行する機能と、実行後、前記1を加算された文字サイズ分全て転送できたか否かを判断する機能と、全て転送できた場合に転送後の末尾の文字に '\0' を上書きする機能と、を実現させることを特徴とする。
【0010】
上記において、全て転送できた場合に転送後の末尾の文字に '\0' を上書きする機能に替えて、実行後の転送する文字サイズ(R3)の値を判定して、ゼロ以外であれば、'\0' を上書きしない機能を実現させることが、好適である。
【発明の効果】
【0011】
RXファミリRX600シリーズCPU命令セットの文字列操作命令を用いてRXCコンパイラにおける標準ライブラリ関数であるstrncat関数の動作を実現する本発明の方法及びプログラムには、次のような効果がある。
連結する文字数を1文字分増やすことで、連結後の余分なメモリアクセスを発生させない。また、連結した文字に '\0' が含まれるかを判断するコストを不要とする。
この結果、strncat関数のオブジェクトサイズは、実行速度優先の場合に、使用前の 69バイトに対して、使用後には、37バイトに縮小できる。
加えて、実行速度数は、使用前と比較して、100文字を連結する場合、約12%(8分の1)に短縮できる。
【図面の簡単な説明】
【0012】
【図1A】標準ライブラリ関数のうち、文字列連結を行なうstrncat関数の動作を示したフローチャートである。
【図1B】図1Aのフローチャートに相当するstrncat関数の動作をC言語で示した図である。
【図2】strncat関数をRXファミリCPU命令で示した図である。
【図3】RXファミリCPUの文字列操作命令であるSMOVUの動作を示したフローチャートである。
【図4】strncat関数を、SMOVU命令を使用して実現した場合を示した図である。
【図5A】strncat関数の仕様に合わない場合のプログラム例を示した図である。(a)はstrncat関数の正しい動作、(b)はSMOVU命令を使用した場合の間違った動作、(c)はSMOVU命令を使用した場合の正しい動作をそれぞれ示している。
【図5B】(a)はstrncat関数の正しい動作、(b)はSMOVU命令を使用した場合の正しい動作をそれぞれ示している。
【図5C】(a)はstrncat関数の正しい動作、(b)はSMOVU命令を使用した場合の正しい動作をそれぞれ示している。
【図6A】本発明により、strncat関数の仕様に合わせて、SMOVU命令を使用した場合の動作を示したフローチャートである。
【図6B】本発明により、strncat関数を、SMOVU命令を使用して実現した場合を示した図である。
【発明を実施するための形態】
【0013】
本発明は、RXCコンパイラが用意する標準ライブラリ関数のうち文字列連結を行う文字列連結関数であるstrncat関数に対して、文字列操作命令を直接当てはめることによりstrncat関数の動作を実現する方法及びプログラムであり、演算処理装置により実行される。文字列操作命令として、文字列転送命令であるSMOVU命令を用いる。
【0014】
本発明の実施形態を説明するに先立って、文字列連結を行うstrncat関数の動作(図1A、図1B、図2)及び文字列転送命令であるSMOVU命令の動作(図3、図4)を説明する。
【0015】
図1Aは、標準ライブラリ関数のうち、文字列連結を行なうstrncat関数の動作を示したフローチャートである。strncat関数は、記憶領域における連結先アドレス p、記憶領域における連結元アドレス S2、及び、連結する(すなわち転送する)文字サイズ(バイト数)N を入力データ(引数)とする(ステップ11)。そして、連結先アドレス p の文字列の終端に、連結元アドレス S2 の文字列を、N(N>0)を上限の文字サイズとして連結する動作を行う。
【0016】
先ず、連結する連結元アドレス S2 の文字サイズが0より大きいか否かを判断する(ステップ12)。文字サイズが0の場合は、連結先アドレス p の終端に '\0' を付加する(*p='\0')(ステップ13)。ステップ12において、文字サイズが0より大きい場合は、連結する文字列が '\0' であるか否かを判断する(ステップ14)。連結する文字列が '\0' の場合は、連結先アドレスpの終端に '\0' を付加する(*p='\0')(ステップ13)。ステップ14において、連結する文字列が '\0' でない場合は、連結先アドレスpに連結元アドレスから1文字転送する(ステップ15)。続いて、連結先アドレスを更新し(p++)、連結元アドレスを更新し(S2++)、文字サイズNを1つ減らす(N--)。その後、ステップ12に戻り、処理を繰り返す。こうして得られるstrncat関数の返却値は、連結先アドレスpの値となる。
【0017】
図1Bは、図1Aのフローチャートに相当するstrncat関数の動作をC言語のソースで示した図である。
【0018】
本発明では、strncat関数の動作を実現するために、図1BのC言語で示したソースから作成される命令は使用せずに、文字列操作命令のうち文字列検索命令である SUNTIL.B命令、及び、文字列転送命令であるSMOVU命令 を使用する。なお、図1BのC言語のソースでは、連結先アドレスpの文字列の終端を指すために、S1 の文字列長として標準ライブラリ関数 strlen を使用しているが、これにも文字列操作命令を使用する。
【0019】
図2は、strncat関数をRXファミリCPU命令で示した図である。
図2では、文字列を連結するために、連結する文字サイズ分だけ、文字転送を繰り返している。そのため、繰り返しのために分岐する命令の実行コストが、文字サイズ分だけ必要となる。また、もし、分岐をさせずに、文字転送のみを連続実行させた場合には、転送する回数分だけ、命令のサイズが増えることとなる。
【0020】
図3は、RXファミリCPUの文字列操作命令であるSMOVU命令の動作を示したフローチャートである。SMOVU命令は、記憶領域における文字列の連結先アドレスR1 、記憶領域における連結元アドレスR2、及び、連結する(転送する)文字サイズ R3 を入力データとする(ステップ31)。そして、R2 を転送元アドレスとして、R1 の転送先アドレスに、 '\0' が検出されるまで、R3 を上限の転送サイズ(バイト数)として、アドレス加算方向に文字列転送を行なう。ただし、命令実行後のR1, R2 の値は不定となる。
【0021】
先ず、連結する連結元アドレス R2 の文字サイズが0より大きいか否かを判断する(ステップ32)。文字サイズが0の場合は、処理を終える。ステップ32において、文字サイズが0より大きい場合は、連結先アドレス R1 に連結元アドレスから1文字転送する(ステップ33)。続いて、連結先アドレス R1 を更新し(R1++)、連結元アドレス R2 を更新し(R2++)、文字サイズR3を1つ減らす(R3--)(ステップ34)。次に、連結した文字が '\0' であるか否かを判断する(ステップ35)。文字が '\0' である場合は、処理を終える。ステップ35において文字が '\0' でない場合は、ステップ32に戻り、処理を繰り返す。
【0022】
本発明では、strncat関数の動作を実現するために、文字列の連結処理においてこの SMOVU 命令を使用する。
【0023】
図4は、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命令で代入する。
【0024】
ただし、図4の方法では、strncat関数の仕様と食い違いが発生してしまう。
【0025】
図5Aは、strncat関数の仕様に合わない場合のプログラム例を示した図である。
図5Aは、strncat(S1,"123\0",4)のstrncat関数を実行する場合の例である。(a)はstrncat関数の正しい動作、(b)はSMOVU命令を使用した場合の間違った動作をそれぞれ示している。
【0026】
このプログラムを実行した正しい動作結果では、(a)に示すように連結後の文字列は "ABC123\0"となるべきだが、実際には(b)に示すようにSMOVU命令をそのまま使用した場合の間違った動作結果では、連結後の文字列が"ABC123\0\0" と連結部分の文字列の末尾に余分な '\0' が付加されてしまう。これは、SUNTIL.B命令が、転送文字数の最後の文字(4文字目)として転送した '\0' を、転送文字数に含めてしまうのが原因である。SUNTIL.B命令は、その動作の仕様として、最後に転送する文字が、'\0' の場合と、'\0' 以外の場合との区別をしていない。そのため、SUNTIL.B命令の実行後に、最後に転送した文字が '\0' か否かを判断して、'\0' であれば、末尾に '\0' を付加しないようにする必要がある。
【0027】
しかし、最後に転送した文字を判断するためには、そのアドレスを計算する命令と、アドレスを代入するレジスタ、計算したアドレスから値をロードする命令が必要となり、その分のコストが増えてしまう。
【0028】
これを踏まえて、strncat関数の仕様に合わせて、SMOVU命令の使用方法を変更する。
図5Aの(c)、図5Bの(b)及び図5Cの(b)は、変更されたSMOVU命令の使用方法に基づく正しい動作結果を示した図である。図5B及び図5Cの(a)はstrncat関数の正しい動作である。なお、図5Bは、strncat(S1,"123\0",3)のstrncat関数を実行する場合の例であり、図5Cは、strncat(S1,"1234\0",3)のstrncat関数を実行する場合の例である。
【0029】
図6Aは、strncat関数の仕様に合わせて、SMOVU命令を使用した場合の動作を示したフローチャートである。
図3と同様に、記憶領域における文字列の連結先アドレスR1 、記憶領域における連結元アドレスR2、及び、連結する(転送する)文字サイズ R3 を入力データとする。
【0030】
先ず、転送後の末尾となるアドレスを求めるために、連結先アドレスに文字サイズを加算する(R4=R1+R3)(ステップ61)。次に、文字サイズ R3 に1を加算する(R3=R3+1)(ステップ63)。その後、図3と同様にSMOVU命令を実行する(ステップ64)。実行後、SMOVU命令により文字サイズ分全て転送できたか否かを判断する(ステップ65)。文字サイズ分全て転送できた場合は、転送後の末尾の文字に '\0' を上書きする(*R4= '\0' )(ステップ66)。文字サイズ分全て転送できなかった場合は、処理を終える。
【0031】
図6Bは、図6Aのフローチャートに相当し、strncat関数を、SMOVU命令を使用して実現した場合を示した図である。
【0032】
SMOVU命令の動作では、転送する文字が '\0' か否かを判断する前に転送をするため、最後に転送した文字が '\0' 以外であったか否かを判断できない。そこで、'\0' 以外だった場合には、もう1文字を転送するように、転送する文字サイズに1を加算する。これにより、転送する文字サイズ分を全て転送できた場合には、本来の文字サイズ(加算前の値)の終端は、必ず '\0' 以外となる。この時、余分に1文字多く転送してしまっているが、この位置は、本来 '\0' を付加する位置なので、転送後に、'\0' を上書き(ストア)すればよいことになる(図5C(b)参照)。
【0033】
もし、余分に転送した1文字が '\0' の場合であっても、'\0' を上書き(ストア)するだけである(図5B(b)参照)。転送する文字列の途中に '\0' があった場合には、SMOVU命令の実行後の転送する文字サイズR3 の値を判定して、ゼロ以外であれば、'\0' を上書き(ストア)しなければよい(図5A(c)参照)。
【0034】
このように、SMOVU命令により、余分に1文字多く転送をしてしまうが、結果は strncat関数と同じにすることが可能である。
【0035】
本発明によるSMOVU命令を使用してstrncat関数の動作を正しく実現する方法をまとめると次の通りとなる。
(i)SMOVU命令で転送する文字サイズの文字数を1文字増やす(指定された文字数よりも1文字多く転送する)。
(ii)SMOVU命令実行後の、残文字数がゼロであれば(文字数分を全て転送できた場合)、転送後の文字列の終端文字を '\0' で上書きする。残文字数がゼロ以外であれば、転送する文字の途中に '\0' があったことを示す( '\0' まで転送した)ことを示すので、 '\0' で上書きはしない。

【特許請求の範囲】
【請求項1】
文字列転送命令を使用して標準ライブラリ関数である文字列連結関数の動作を演算処理装置により行う方法であって、演算処理装置が、
記憶領域における文字列の連結先アドレス(R1)、記憶領域における連結元アドレス(R2)、及び、連結する文字サイズ(R3)を入力データとするステップと、
前記連結先アドレス(R1)に文字サイズ(R3)を加算することにより、転送後の末尾のアドレス(R4)を得るステップと、
前記文字サイズ(R3) に1を加算することにより、1を加算された文字サイズを得るステップと、
前記転送後の末尾のアドレス(R4)、前記連結元アドレス(R2)、及び、前記1を加算された文字サイズ(R3+1)を入力データとして、文字列転送命令を実行するステップと、
実行後、前記1を加算された文字サイズ分全て転送できたか否かを判断するステップと、
全て転送できた場合に転送後の末尾の文字に '\0' を上書きするステップと、を有することを特徴とする
文字列転送命令を用いて文字列連結関数の動作を行う方法。
【請求項2】
請求項1において、全て転送できた場合に転送後の末尾の文字に '\0' を上書きするステップに替えて、実行後の転送する文字サイズ(R3)の値を判定して、ゼロ以外であれば、'\0' を上書きしないステップを有することを特徴とする文字列転送命令を用いて文字列連結関数の動作を行う方法。
【請求項3】
文字列転送命令を使用して標準ライブラリ関数である文字列連結関数の動作を演算処理装置に行わせるプログラムであって、演算処理装置に、
記憶領域における文字列の連結先アドレス(R1)、記憶領域における連結元アドレス(R2)、及び、連結する文字サイズ(R3)を入力データとする機能と、
前記連結先アドレス(R1)に文字サイズ(R3)を加算することにより、転送後の末尾のアドレス(R4)を得る機能と、
前記文字サイズ(R3) に1を加算することにより、1を加算された文字サイズを得る機能と、
前記転送後の末尾のアドレス(R4)、前記連結元アドレス(R2)、及び、前記1を加算された文字サイズ(R3+1)を入力データとして、文字列転送命令を実行する機能と、
実行後、前記1を加算された文字サイズ分全て転送できたか否かを判断する機能と、
全て転送できた場合に転送後の末尾の文字に '\0' を上書きする機能と、を実現させることを特徴とする
文字列転送命令を用いて文字列連結関数の動作を行うプログラム。
【請求項4】
請求項3において、全て転送できた場合に転送後の末尾の文字に '\0' を上書きする機能に替えて、実行後の転送する文字サイズ(R3)の値を判定して、ゼロ以外であれば、'\0' を上書きしない機能を実現させることを特徴とする文字列転送命令を用いて文字列連結関数の動作を行うプログラム。

【図1A】
image rotate

【図1B】
image rotate

【図2】
image rotate

【図3】
image rotate

【図4】
image rotate

【図5A】
image rotate

【図5B】
image rotate

【図5C】
image rotate

【図6A】
image rotate

【図6B】
image rotate


【公開番号】特開2012−208869(P2012−208869A)
【公開日】平成24年10月25日(2012.10.25)
【国際特許分類】
【出願番号】特願2011−75608(P2011−75608)
【出願日】平成23年3月30日(2011.3.30)
【出願人】(000233055)株式会社日立ソリューションズ (1,610)
【Fターム(参考)】