機械語なら俺に質問しろ!

このエントリーをはてなブックマークに追加
952デフォルトの名無しさん:2012/12/19(水) 05:45:13.54
訂正

LSI-C80 → LSI C-80
LSI-C86 → LSI C-86
953デフォルトの名無しさん:2012/12/19(水) 08:35:02.17
先ず第一に、80と86ではコードジェネレータが違うこと。
→80版は86版ほどタイトなコードは生成しない。
第二に、初回のジャンプを省略しようかと言うレベルの話をしていること。
→8086のコードは参考にしかならない。
全く的外れと言わざるをえない。
954デフォルトの名無しさん:2012/12/19(水) 12:27:27.27
>>953
>先ず第一に、80と86ではコードジェネレータが違うこと。
>→80版は86版ほどタイトなコードは生成しない。

じゃあどんなコード吐くの? 参考に晒してくれたっていい罠。

>第二に、初回のジャンプを省略しようかと言うレベルの話をしていること。

少なくとも>>930-931はそんな話してない訳だが。

>→8086のコードは参考にしかならない。

参考になるならいいじゃん。アホか?
955デフォルトの名無しさん:2012/12/19(水) 12:52:55.10
>>953
>第二に、初回のジャンプを省略しようかと言うレベルの話をしていること。

そこまで気にすんなら関数呼び出しのコストも削れよw
956デフォルトの名無しさん:2012/12/19(水) 13:14:11.67
>>954 名前:デフォルトの名無しさん[sage] 投稿日:2012/12/19(水) 12:27:27.27
そう真っ赤になるなって。自分の投稿時間でも眺めて和めよ。
957デフォルトの名無しさん:2012/12/19(水) 13:40:48.46
和んだ
958デフォルトの名無しさん:2012/12/19(水) 13:47:51.40
>>930
>8085用のLSIC-80で、3行分溜めてからまとめるコードを以下のように書いていた。
>  strcpy(dst,1行目);
>  strcat(dst,2行目);
>  strcat(dst,3行目);

>strcpyした末尾アドレスをそのまま返せばstrcpyと同程度の性能になるのに許せん!

実際その部分が全体のパフォーマンスにどの程度影響及ぼしてるわけ?
多少効率が悪かろうとも、間に合ってるなら以降の作業は徒労ということになるが。
959931:2012/12/19(水) 16:54:57.38
sprintfで実数変換使うと間に合わない、整数変換でも幾つもやると同様、ぐらい。
4800BPSを4CH同時に入出力してて、あるCHがこの例です。1CHだけならイイが、
4CHみんな整数変換とかstrcatを使うと危ないので軽くできればしておきたいです。

間に合わない=受信ringで周回遅れが発生して行の再構成が失敗します。
clockは3.072MHzで、これを8253で分周して8251用と10mS割込用のclock作ってます。
まあ、暇だから最適化で遊んでるってのもありますけど。
960デフォルトの名無しさん:2012/12/19(水) 17:19:47.09
sprintf() 既に使ってるなら、

sprintf(dst, "%s%s%s", 1行目, 2行目, 3行目);

とか書けば保守性は向上するな。
sprintf()の実装や連結する文字列のバイト数によっては負荷ともなりうるが。
961デフォルトの名無しさん:2012/12/19(水) 17:23:55.25
>>959
>sprintfで実数変換使うと間に合わない、整数変換でも幾つもやると同様、ぐらい。

重い箇所分かってんなら最適化で一番効果が期待できるのはそこだが?
962デフォルトの名無しさん:2012/12/19(水) 17:38:54.44
>>930
>8085用のLSIC-80で、3行分溜めてからまとめるコードを以下のように書いていた。
>  strcpy(dst,1行目);
>  strcat(dst,2行目);
>  strcat(dst,3行目);

最初からひとつのバッファに3行分溜めればまとめる必要もねんじゃね?
963デフォルトの名無しさん:2012/12/19(水) 17:50:04.64
Cで速度最優先なら、str系ではなく、自分で長さを保持して全てmemcpy。
それでもダメってところで、ようやくアセンブラ。
964デフォルトの名無しさん:2012/12/19(水) 18:01:44.75
>sprintfで実数変換使うと間に合わない、

LSI C-80って基本的な仕様が古いみたいだし、実数はfloatでも一旦doubleに昇格してから
演算するとかですげえ遅いんじゃないの?C89以前では普通だったけど。

実数が本当に必要かも検討するべき。
965デフォルトの名無しさん:2012/12/19(水) 18:14:14.31
LSI Cは実数遅いよ。余りチューンしてないってpnoriさんが言ってた。
まして80じゃぁしょうがない。多分自力で固定小数点数ライブラリを作るのが一番。
966デフォルトの名無しさん:2012/12/19(水) 18:18:40.15
>>963
>Cで速度最優先なら、str系ではなく、自分で長さを保持して全てmemcpy。

8085での実装なら、memcpy()よりstrcpy()の方が速い。
967966:2012/12/19(水) 19:45:54.67
訂正

8085での実装なら、memcpy()よりstrcpy()の方が速い。

8085での実装で、場合分けによる処理の最適化をしない前提なら、memcpy()よりstrcpy()の方が速い。

LSI C-80での実装がどうなってるかは知らん。
968デフォルトの名無しさん:2012/12/19(水) 20:18:33.62
>>959
暇ならLSI C-80に>>951のソース喰わしたらどういうコード吐くかやってみて
969931:2012/12/20(木) 06:43:03.90
%16    ; ここがwhile の行。
__2:
    LDAX    D
    MOV    M,A
    ORA    A
    JZ    __3
%17
    INX    H
%18
    INX    D
%19
    JMP    __2
__3:
%20
    RET
JMPが2つあるのでサイズ最小ではないけど、素直なコードですね。
_asm_が混じるcコードより可読性はグー!
memcpyよりstrcpyのほうが速いのは知って使ってます。
970デフォルトの名無しさん:2012/12/20(木) 13:33:15.10
>>969
成る程、86版とは違うコードになるんだなあ。
1ループ中にジャンプ命令が2回あるからコピーする文字列が長いと86版に比べて効率は悪いが、
逆に、コピーする文字列が""で、結果1バイトしかコピーしない場合には効率は良いとも言えるな。

    JZ    __3
(略)
__3:
    RET

のところは

    RZ

になってればループを抜けなかった際のサイクル数が少なかったのに惜しい。
971931:2012/12/20(木) 13:55:00.11
R<条件> と、C<条件> はLSIC-80に実装されてないんですよね。なので、
  if( r_ptr ^ w_ptr )
    func( );   は、lda r_ptr、lxi H,w_ptr、xra M、JZ 飛び越し、call func
が出ます。 これを lhld r_ptr、mov A,H、xra L、cnz func と、最適化しました。
(r_ptrとw_ptrは並んでいるので) メインループ中にこれが4種類あるので、
メモリアクセス削減になってます。
972デフォルトの名無しさん:2012/12/20(木) 14:52:08.26
2ちゃんもひと少なくなったな
973931:2012/12/20(木) 17:14:18.48
8085用 romlibのcコード読んでたら、strncat( ) は目的stringの末尾にnullをsetする
だけなのに、strncpy( ) は、目的stringがソースより長いとき 「残りを全て0で埋める」
ように書かれていました。 これは実害は無いにしろ、「余計なこと」 ですね。
974931:2012/12/22(土) 05:50:34.74
>>970 ループ中に毎回NOPのジャンプが実行されるのが、素直なコードの悔しい所ですね
char*stpcpy2(char *s, const char *t) {
   goto do2;
do1: s++; t++;
do2: if (*s = *t) goto do1;
   return(s);
} これだと頭のジャンプ1回が静的動的に無駄なだけで、あとはASMのコードと同性能
_asm_で書くより可読性は良いから、cでの実装にはこれがベストかと。
975デフォルトの名無しさん:2012/12/22(土) 09:31:32.92
>>973
それがstrncpy()の奇妙な仕様。なので、余計ではない。
976931:2012/12/22(土) 12:37:11.14
え〜?? ほんとだ。わざわざそのように断ってある。なんでこんなことに
なってるんだろう? 末尾nullだけでは困る事情がかつてあったのだろうか。
977931:2012/12/22(土) 13:08:23.06
>>974 をfor( ; (*s=*t); s++,t++ ) ; と書くと、素直版と同じコードになっちゃうんですね。
forで、頭JMPで実行条件判定に飛び込むパターンも見たことあるのですが、何が
決め手になるのかよく判らないなあ。
978931:2012/12/28(金) 04:30:02.13
strcat( d, s ) の中身:strcpy(d+strlen(d),s); return( d ); の展開が↓
  push  H
  push  D
  pop   H
  push  H
  push  H
  call   LAUTO4
  call   strlen
  mov   C,L
  mov   B,H
  call   LAUTO4
  DAD  B
  POP  D
  call   strcpy
  call   LAUTO2
  pop   B
  pop   B
  ret  コールが5回もあるの(*o*) あんまりだ!
979931:2012/12/28(金) 04:36:00.53
ASMにしてみたのがこれ: 合ってるよね?
strcat_:  ; char  *strcat(char *s, const char *t) {
  push   H        ; 第1引数を保存
  mov   A,M
  inx    H
  ora    A
  jnz    $-3        ; 末尾を探す
  dcx    H         ; 末尾アドレスに戻す
  call    strcpy_      ; その位置にcopy
  pop    H         ; 第1引数を復元(HL=返却値)
  ret
980デフォルトの名無しさん:2012/12/28(金) 08:37:20.92
>>979
call して pop hl する代わりに、pop af して jmp してはどうだろう。
981デフォルトの名無しさん:2012/12/28(金) 08:38:15.51
あ、なんだ、保存する必要さえなかったか。
982デフォルトの名無しさん:2012/12/28(金) 09:39:18.01
>>979
速度優先なら、PUSH H〜POP HはBC に退避〜復帰させた方が早い。
但しstrcpy()の中で破壊されないこと前提になるから保守性は低下する。
strcpy()も展開した方がいいな、速度優先なら。
983デフォルトの名無しさん:2012/12/28(金) 09:47:24.05
失業したおっさんらに質問です
OS創りたいのですが
何から始めれば良いでしょう
984デフォルトの名無しさん:2012/12/28(金) 09:48:59.43
>>983
PCを拾ってくる
985デフォルトの名無しさん:2012/12/28(金) 09:50:44.89
>>983
バイトでもいいから仕事に就く
986デフォルトの名無しさん:2012/12/28(金) 09:52:47.51
>>983
まずOSを創ります → 終了
987デフォルトの名無しさん:2012/12/28(金) 10:35:15.37
マジレスするが、まずは失業しておかないと、創る時間とれないよ
988デフォルトの名無しさん:2012/12/28(金) 11:29:19.56
失業せずにOSを作れないようなら、シングルタスクのOSを作る頭脳しかない。
989デフォルトの名無しさん:2012/12/28(金) 13:27:11.77
今日の大喜利会場はここですか?
990979:2012/12/29(土) 04:06:22.83
>>980 動作変わっちゃいませんか?返却値は目的stringの頭ですけど、
strcpyする時は目的stringの末尾ですよね。

>>982 速度だけ優先ならそうですね。libであることを考慮すると速度・サイズ両面で
納得のゆく落とし所、ということで979にしました。 同サイズで速度ちょっと改善版:
strcat_:  ; char  *strcat(char *s, const char *t) {
  push   H        ; 第1引数を保存
  xra   A
  cmp   M
  inx    H
  jnz    $-2        ; 末尾を探す
  dcx    H         ; 末尾アドレスに戻す
  call    strcpy_      ; その位置にcopy
  pop    H         ; 第1引数を復元(HL=返却値)
  ret
徹底するなら速度版とサイズ版2種のlibを用意するのがイイですね。
991979:2012/12/29(土) 04:13:24.07
発端は、「libは、コンパイラ開発メーカーの(自分より頭のイイ)人が書くのだから、
速度・サイズ両面で充分練られた物だろう」 と思いこんでいたのが違った、という話。
乗除算のルーチンなんかはきっちりコンパクトでしたけどね。
stringがこんだけルーズだと、printf系なんか読んだら憤死するかも(^o^)
992デフォルトの名無しさん:2012/12/29(土) 05:53:01.81
うめますね(^o^)
993デフォルトの名無しさん:2012/12/29(土) 05:53:36.75
うめ
994デフォルトの名無しさん:2012/12/29(土) 08:01:12.51
うめ
995デフォルトの名無しさん:2012/12/29(土) 08:04:54.76
10年も続いたのね、このスレ。まだ8085の話したいから立てました(w

http://toro.2ch.net/test/read.cgi/tech/1356735624/
996デフォルトの名無しさん:2012/12/29(土) 08:38:16.29
うめ
997デフォルトの名無しさん:2012/12/29(土) 09:16:36.24
JR $-2
998デフォルトの名無しさん:2012/12/29(土) 09:17:11.08
うめ
999デフォルトの名無しさん:2012/12/29(土) 09:21:04.33
うめ
1000デフォルトの名無しさん:2012/12/29(土) 09:21:32.93
76
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。