split2/split3
Perl使いであるところの私の願望である、無制限長分割を実装してみました。
splitもいい命令なんだけど、どう分割するかを決めてかからないといけないのは、俺にとってはちょとつらいので。
numalias split2_base numalias split2_sepa numalias split2_start numalias split2_count numalias split2_pos numalias split2_temp ------ ------ ;============================== ; split2 ;============================== ;機能:無制限にスプリットする。 ;引数:いくつ分割したかを格納する数字変数、分割対象の文字列、区切文字(半角一文字)、区切ったデータを格納する文字変数の最初の番号、最大分割数 ;付記:最大分割数を0以下にすると、無制限分割になります。 ;付記:分割されなかった分は、最後の文字列変数に全て格納されます。 *split2 getparam i%split2_count,$split2_base,$split2_sepa,%split2_start,%split2_sepa mov %split2_pos,0 ; カーソルの位置を初期設定 mov %%split2_count,1 ; 分割カウンタ len %split2_base,$split2_base ; 元文字列の長さをはかる。 if %split2_base < 1 return ; 長さが1未満なら、何もせずに終わる。 ; ループ前 mov $%split2_start,"" *split2_loop mid $split2_pos,$split2_base,%split2_pos,1 ; 対象文字列から一文字取ってくる。 ; 繰り上がり処理か通常処理か。 ; 取ってきた文字と区切文字が等しくない場合→通常処理 notif $split2_pos = $split2_sepa goto *split2_normal ; 等しくても、無限分割でなく、かつ分割数がすでに最大分割数に到達していれば、通常処理。 if %split2_sepa > 0 && %%split2_count = %split2_sepa goto *split2_normal *split2_nextshard ; 繰り上がり処理 inc %split2_start ; 分割後の格納変数を一つ進める。 inc %%split2_count ; 分割数を増やす。 mov $%split2_start,"" goto *split2_next *split2_normal ; 通常処理 add $%split2_start,$split2_pos ; それをかけらに追加する。 *split2_next inc %split2_pos ; カーソルを一つ進める。 if %split2_pos >= %split2_base return ; カーソルの位置が、長さを越えたら終わる。 goto *split2_loop ;============================== ; split3 ;============================== ;機能:無制限にスプリットする。 ;引数:いくつ分割したかを格納する数字変数、分割対象の文字列、区切文字、区切ったデータを格納する文字変数の最初の番号、最大分割数 ;付記:最大分割数を0以下にすると、無制限分割になります。 ;付記:分割されなかった分は、最後の文字列変数に全て格納されます。 ;付記:区切文字は複数バイトあり *split3 getparam i%split2_count,$split2_base,$split2_sepa,%split2_start,%split2_sepa mov %split2_pos,0 ; カーソルの位置を初期設定 mov %%split2_count,1 ; 分割カウンタ len %split2_base,$split2_base ; 元文字列の長さをはかる。 if %split2_base < 1 return ; 長さが1未満なら、何もせずに終わる。 len %split2_temp,$split2_sepa ; ループ前 mov $%split2_start,"" *split3_loop mid $split2_pos,$split2_base,%split2_pos,%split2_temp ; 対象文字列から一文字取ってくる。 ; 繰り上がり処理か通常処理か。 ; 取ってきた文字と区切文字が等しくない場合→通常処理 notif $split2_pos = $split2_sepa goto *split3_normal ; 等しくても、無限分割でなく、かつ分割数がすでに最大分割数に到達していれば、通常処理。 if %split2_sepa > 0 && %%split2_count = %split2_sepa goto *split3_normal *split3_nextshard ; 繰り上がり処理 inc %split2_start ; 分割後の格納変数を一つ進める。 inc %%split2_count ; 分割数を増やす。 mov $%split2_start,"" add %split2_pos,%split2_temp goto *split3_next *split3_normal ; 通常処理 mid $split2_pos,$split2_pos,0,1 add $%split2_start,$split2_pos ; それをかけらに追加する。 inc %split2_pos ; カーソルを一つ進める。 *split3_next if %split2_pos >= %split2_base return ; カーソルの位置が、長さを越えたら終わる。 goto *split3_loop
split2は全部文字列変数になってしまうものの、文字列にあわせた分割を可能にする。
split3はsplit2に加えて、区切り文字を2バイト以上にすることができる。(その分、遅くなっている、と思う)
22.dllと組み合わせて、自前のセーブやロードをするのに使えると思う。