![]() |
Message Log 21 | Return to Parent Menu |
Last Updated by 07/01/05(Fri) |
| |||
やっぱり 2000 年もアセンブラッ!!だねっ |
| |||
| |||
: Ichi [2000/04/30 Sun 06:56:16] [210.237.206.8] 調査結果 to Miniraさん >これを利用してプログラミングの勉強をしようと思うのですが、やりかたはあるでしょうか。 アセンブリ言語のサイトなのでアセンブラを紹介します。 THE ARROWSOFT ASSEMBLERというのが、無料で使えますので、 試してみてください。(確かMASM 2.0互換です。バグまでも) http://www.vector.co.jp/soft/dos/prog/se014771.html to ずとしさん: >@ジャンプテーブルの件。 >つまりはすべて条件ジャンプのif-else if-else -...... で >順番も考えてならべると、速くなるであろう、 調査してみました。結果、256の場合はジャンプテーブルが (調査した中では)一番速いという結論になりました。 そしてただのif-elseだけでは論外でした。 (http://www7.freeweb.ne.jp/computer/ichi98/opinion/t0002.html) というわけで、NEWさんのおっしゃる様に、まず 出現頻度の高い命令「だけ」個別にチェックして、そのあと ジャンプテーブル等の速い方法で分岐すれば良いと思います。 >なので、CPU実行プログラムと、液晶画面描画プログラムとを、頻繁に行き来するんですよ。 どこまで描画された(はず)かのカウンタを作って、 実行が中断したらそこまで描画する、というはどうですか? Minira [2000/04/29 Sat 19:02:05] [210.253.226.120] はじめまして。 知り合いからPC98のノートをもらいました。 表面がフェラーリの色に塗られているので、心配でしたが動くようです。 ハードディスクは合計で500Mくらいあると思います。Windows3.1が入っています。 これを利用してプログラミングの勉強をしようと思うのですが、やりかたはあるでしょうか。 よろしくお願いします。 yutaro [2000/04/27 Thu 23:18:12] [152.166.28.123] ずとしさんアドバイスありがとうございました。 早速がんばってみます。 Ichi [2000/04/26 Wed 06:34:30] [210.237.205.247] http://www7.freeweb.ne.jp/computer/ichi98/ さっき http://www.vesa.org/ へ行ったら、仕様書が有料の様で面食らいました。 >ずとしさん >えーと、僕のはスタンダードでしたねぇ。最適化の設定が >いじれねぇと思ったらそういうことなんですね。 裏技があるんですよね、これが。でもここで書くのは相応しくないと思うので、 メールがいいでしょうか。 ずとし [2000/04/26 Wed 00:34:39] [210.230.144.173] やっぱりしばらく厄介になることにしてもいいですか。 >standardだと高度な最適化をしてくれないので別です。 えーと、僕のはスタンダードでしたねぇ。最適化の設定が いじれねぇと思ったらそういうことなんですね。 プロフェッショナルでコンパイルかけると違うモノができるわけですな。 人のやつ間借りして使わしてもらうとよさそうですね。 @ジャンプテーブルの件。 つまりはすべて条件ジャンプのif-else if-else -...... で 順番も考えてならべると、速くなるであろう、 ということであってますよね。 Cで書き直すときについでにやるということで先送ります。はぁ。 大変参考になりました。 ....実は2バイト命令で同様の超多方向分岐がもう一個要ったりします。 >エミュレータ作ってるんだけど、速度的に問題なかったんで、ゲーム >ボーイなら普通にCで書いても行けそうな気がしますが...。 エミュレーターでなしにデバッガーを作りたいのです。 ブレークポイントでCPU止めると、同時に画面の描画も止まったりするやつです。 描画ラインの途中とかでも、ぴたぁっと。 なので、CPU実行プログラムと、液晶画面描画プログラムとを、頻繁に行き来するんですよ。 133MHzの開発に使ってるやつでは、動作はもはやあきらめ状態です。 @メンバ関数の呼び方 クラスへのポインタからいくらか行ったところに、 メンバ関数へのジャンプ命令が並んでたのをトレース中に見た気がします。 ヘルプには呼び出せないって書いてあったけど、 そのへんいじくりまわしてれば、一応可能なんじゃないでしょうか。 ただ、インラインアセンブラがメンバ関数呼び出しの書式を サポートしてないだけじゃないかと思ってます。 適当なこと言ってるので、信用しないでくださいね。 長くなりまして。ではまた。 yutaro [2000/04/25 Tue 22:28:10] [152.200.157.145] 質問させていただきます。 Visual C++のインラインアセンブラから クラスのメンバ関数をCALLしたいんですが、 CALLの方法を知っている方アドバイスをお願いします。 よろしく!! houbou [2000/04/25 Tue 19:19:13] [203.104.140.200] Codename:F ども。もう忘れられているhoubouです。 そういえば今までDOSのLIB.EXE互換コマンドは見かけなかったの ですがついこの間見つけたので報告しておきます。 ftp://ftp-fd.inf.fh-rhein-sieg.de/pub/freedos/local/ lib-sk???.zipというがそれです。 では。 NEW [2000/04/25 Tue 09:11:34] [210.251.66.227] >VCのほうが速いんですねぇ。げーん。 >なんも考えずに、Cで書いてないところまでアセンブラで組みかけてしまいました。 >直した方がいいんですね。 せっかく書いたのだから、そのまま使ってもよいとは思います。 ただ、デバッグ等を考えると、Cの方がよい場面が多いです。 >でも、ゲームボーイのCPU256命令文のジャンプテーブルとか作っちゃったし。 >switch~ case: で書くの、めんどくさそう。 ジャンプテーブルを使用すると、間接ジャンプを使う事になります。 間接ジャンプは、ジャンプ先がその命令を実行するまで確定しない ので、最適化でもっとも避けるべき方法だったりします(^^; 普通の条件ジャンプ等は、分岐予想を行い、かなり高い確度で跳び先を 予想し、ジャンプする前から跳び先の命令のデコードを始め、パイプ ラインが乱れない様になっています。パイプラインが機能して始めて、 規定のクロック数で動作しますので、一度乱れるとめちゃくちゃ遅く なってしまいます。 ただし、VCの場合はswitch〜caseでジャンプテーブルを作るので、 この部分はアセンブラで作っても変わらないと思います。また、256個 なので、数も多いですし。 解決策としては、256個全部の出現確率が一定ではないはずなので、 なるべく頻繁に使われる命令からチェックし、あまり使われない命令を テーブル化するとか、ハッシュ検索を使うとか、アルゴリズムの方で まずは最適化をはかるべきだと思います。アセンブラに置き換える のは、最後の手段でしょう。 >フラグのことですが、Z80とビットの並びが同じならそのままコピーとか考えてたんですけど、 >アセンブラで書かないほうがいいならもういっかぁ。 Z80とは違うと思いますよ。 大学の後輩が、M88とかいうWinで動く懐かしのNEC PC-8800シリーズの エミュレータ作ってるんだけど、速度的に問題なかったんで、ゲーム ボーイなら普通にCで書いても行けそうな気がしますが...。 Ichi [2000/04/25 Tue 07:04:41] [210.237.206.30] http://www7.freeweb.ne.jp/computer/ichi98/ >ずとしさん >VCのほうが速いんですねぇ。 standardだと高度な最適化をしてくれないので別です。 (裏技で最適化もありますが) >CPU256命令文のジャンプテーブル これは多分速いと思います。256なら。20くらいだと なんとも言えないところですが。 ジャンプテーブルはパイプラインを破壊する様ですから。 # でもVCはswitch-caseをジャンプテーブルに最適化するらしい... >澤口@大崎さん >たしかにそれは新機軸ですね。作りが同じなら、余計なタスク >スイッチのない分、DOS 版の方が早くなるでしょう。 >期待してます。わたしも 9801 でしか走らないソフトを多数 >抱えているもので。 ありがとうございます。早速更なる質問をさせていただきます。 >大昔は PC9801 上で PC/AT 用ソフトを走らすためのドライバ >ってのがありましたが。 テキスト画面がある分、98の方が有利なんでしょうかね。(謎) では、質問です。 テキスト画面とグラフィック画面を表現するのに、640*480*16の VGAでは力不足なので、SVGAを使おうと思います。VESAというのが 標準らしいのですが、このとき、画像を表示(ビデオカードに転送)する にはどうしたら良いのでしょうか。 関連サイトでもいいので、教えてください。 ずとし [2000/04/24 Mon 23:05:18] [210.249.23.72] VCのほうが速いんですねぇ。げーん。 なんも考えずに、Cで書いてないところまでアセンブラで組みかけてしまいました。 直した方がいいんですね。 でも、ゲームボーイのCPU256命令文のジャンプテーブルとか作っちゃったし。 switch~ case: で書くの、めんどくさそう。 8ビットCPUだから変数とかほとんど8ビットだし。 8ビットレジスタ上位下位ともに使いまくり。 あー困った。 フラグのことですが、Z80とビットの並びが同じならそのままコピーとか考えてたんですけど、 アセンブラで書かないほうがいいならもういっかぁ。 大ショックなり。 ひとまずアセンブラで続きつくって動くようになってからCに直すかなぁ。 無念。無益。 ものすごく、勘違いでした。テクノロジーの進歩をナメておりました。 しかし新たな興味も沸き立つのでありました。へへへ。 まずは、やっぱり、書物あさりですね。 また、お世話になるかもしれません。 そのときはよろしくお願いします。もっかいはじめまして言うと思いますが。 澤口@大崎 [2000/04/24 Mon 14:16:14] [210.141.243.66] 澤口@大崎です。 to Ichiさん: >遅いからです。98用コードを仮想86モードで動かして、 >VRAM、I/Oポート等へのアクセスを捕まえてやる、 >くらいに干渉を抑えれば速くなるかな、と思いまして。 >Windows上で出来ればいいんですが、Windowsが許して >くれなそうなので、DOS上でやることにしたのです。 たしかにそれは新機軸ですね。作りが同じなら、余計なタスク スイッチのない分、DOS 版の方が早くなるでしょう。 期待してます。わたしも 9801 でしか走らないソフトを多数 抱えているもので。 大昔は PC9801 上で PC/AT 用ソフトを走らすためのドライバ ってのがありましたが。 NEW [2000/04/24 Mon 10:10:42] [210.251.66.227] > movsz/movzxなんかを使えば8bit->32bit変換が movsx/movzxの間違い(^^; >あと、別件ですが、フラグレジスタの各ビットにどのフラグが割り当てられているか。 >と、ビット操作(フラグのじゃなくて)の命令があれば教えていただきたいです。 フラグは、おいらは記憶してませんが、x86の本で、lahf/sahf命令 のところに載っていると思います。 ビット操作って、シフトとかじゃなくて? 何か専用の命令って事ですか? 何か命令ありましたっけ? > ALL NECの8086互換チップであるV30とかは、INS、EXTとかいう謎な命令が ありましたが、普段はand、orとかしか使わないから覚えてない(^^; 出来る限り簡単な命令を組み合わせた方が、高速化にはききますよ。 loop命令なんて、いまや使わないしね。遅いから(互換チップ除く)。 NEW [2000/04/24 Mon 10:01:04] [210.251.66.227] ずとしさん: >そこで疑問があるのですが、VCの最適化を通してはかれたコードと、 >命令表から使える命令を探している状態(つまり初心者)の手書きコードとを比べても、 >手書きのほうが速く動くものなのでしょうか。 これはIchiさんも答えていましたが、VCの最適化コードの方が 速いと思われます。x86は奥が深いですよ〜。 >リスティングではかれたコードと比べると、明らかに命令の数は手書きのほうが少ないのですが、 >動作もよくわからなければ、サイクル表とかもないので、はっきりとわかりません。 実行されるマシンのCPUによって変わるので、一概には言えませんが、 もやはサイクル表はあまり意味を成さない世界です。 > x86 少なくともP6(PentiumPro)以降のアーキテクチャでは、x86命令を デコードして、更に細かいμ命令に置き換わった挙げ句、OOO(Out Of Order) 実行を行うようになっていますし、命令のデコード状態や、キャッシュの 状態等でコロコロと実行速度は変わります。(キャッシュにヒットして いないメモリをアクセスしようもんなら、規定サイクルの数十倍時間 がかかるなんてざらですし...。) 最適化をするなら、正確な時間を測れるプログラムを書いて、実際に 測ってみるしかないです。また、最適化支援ツール(V-Tuneなど)を 使う作戦もありますよ。 >たとえば、32ビットのCPUで8ビット値の取り扱いは遅くなったりしないかなど、 >気になっています。 これも、一概には言えません。x86で8bitの値を扱う方法は、明示的に 32bit中の下位8bitしか使わない、パーシャルレジスタを使うなどの 方法がありますが、P6以降はパーシャルレジスタは使わない方が良い です。つまり、EAX(32bit)、AX(16bit)、AH/AL(8bit)という風に 同じレジスタをそれぞれの精度で使えるには使えますが、これはあん まり好ましくないです。中でも、AX、AHなんかは厳禁とおいらは 思っています。movsz/movzxなんかを使えば8bit->32bit変換が 楽に出来るので、最下位の8bitは使っても良いです。ただし、これらの 命令はP6以降では速いですが、それ以前のCPUでは遅かったりして、 とにかくx86の最適化は歴史を知る事と慣れが必要です。 長くなりました。 Ichi [2000/04/23 Sun 05:42:59] [210.237.205.233] とりあえず計画のページ >澤口@大崎さん レスありがとうございます。やっぱり簡単には呼び出せないんですね。 リアルモードに戻らねばならないとは。 >あえて新作するココロ 遅いからです。98用コードを仮想86モードで動かして、 VRAM、I/Oポート等へのアクセスを捕まえてやる、 くらいに干渉を抑えれば速くなるかな、と思いまして。 Windows上で出来ればいいんですが、Windowsが許して くれなそうなので、DOS上でやることにしたのです。 >ずとしさん >VCの最適化 (略) >手書きのほうが速く動くものなのでしょうか。 初心者のと比べたら、VCが最適化したものが速く動きます。 ずとし [2000/04/23 Sun 02:38:39] [210.249.21.110] はじめまして、8ビットアセンブラ使いでC、C++の勉強を最近やりはじめました。 で、WINDOWSで動くゲームボーイデバッガーを作ってるのですが、 エミュレーション部分の高速化のために、VCのインラインですが、 アセンブリを混ぜてみています。当初のCの勉強という目的がボケてしまっていますが。 そこで疑問があるのですが、VCの最適化を通してはかれたコードと、 命令表から使える命令を探している状態(つまり初心者)の手書きコードとを比べても、 手書きのほうが速く動くものなのでしょうか。 リスティングではかれたコードと比べると、明らかに命令の数は手書きのほうが少ないのですが、 動作もよくわからなければ、サイクル表とかもないので、はっきりとわかりません。 たとえば、32ビットのCPUで8ビット値の取り扱いは遅くなったりしないかなど、 気になっています。知らないところで基本的な勘違いとかもありそうで。 あと、別件ですが、フラグレジスタの各ビットにどのフラグが割り当てられているか。 と、ビット操作(フラグのじゃなくて)の命令があれば教えていただきたいです。 えー、それから、インラインアセンブラ特有の書式について、よくわからないことが多いので、 参考になる情報をいただければ。 お初で聞くばっかりになりますが、どうかよろしくお願いします。 澤口@大崎 [2000/04/22 Sat 15:17:58] [210.141.243.66] 澤口@大崎です。 あまり関係ないんですけど、 BeOS は 5.0 から フリーになってましたね。こいつなら対応している のかも知れない。(無責任モード) ↓ http://www.be.com/products/freebeos/ 澤口@大崎 [2000/04/22 Sat 15:09:18] [210.141.243.66] 澤口@大崎です。 to Ichi さん: プロテクトモードから DOS コールを呼び出すには、 一旦リアルモードに戻ってからコールし、その後再び プロテクトモードに戻る、という手続きを踏みます。 DPMI 規格でサポートされていると思うのですが。 市販やフリーの DOS Extender でもここらの機能はサ ポートされているのが普通です。 ただ、この場合(プロテクトモードからリアルモードの BIOS 呼び出しもそうですが)呼び出しオーバーヘッド が非常に大きくなります。 フリーOS のソースを参考にして、自前でプロテクトモー ドのドライバを実装したほうがパフォーマンスが良くなる と思います。 ところで、PC98 エミュレータって色々あると思いますが ↓ http://www.blk.mmtr.or.jp/~abetti/ あえて新作するココロは? がんばって下さい。 Ichi [2000/04/22 Sat 07:20:48] [210.237.206.18] Ichiのプログラミング小ネタ集 初めまして。Ichiといいます。MASMで検索していたらここを見つけ、 こんなにアセンブリ言語をやっている人が集まるところが今でも あったなんて、と感激しました。過去ログも全部読んで、今 めぼしいサイトを回っているところです。 一応アセンブリ言語(x86系)歴は4年ですが、最近2年はほとんどやってません。 さて、私は今AT互換機で動くPC98エミュレータを作ろうと企んでいるの ですが、いかんせん覚えることが多すぎてなかなかうまくいきません。 これから質問することも多いかと思いますが、一つ、よろしくお願いします。 (長くてすみません) 早速ですが(爆) DOS上で保護モードのプログラムを実行している際に、 当該プログラムはDOSファンクションコールを呼び出せるのでしょうか。 出来るならばどの様に呼び出すのでしょうか。 さかもと [2000/04/14 Fri 18:52:49] [210.171.3.34] さかもとです。 NEW様、歩野零一様、本当にありがとうございました。 う〜ん、かなりお馬鹿な勘違いをしていたようで・・・。 で、肝心の「SSE」の件ですが、 お教えいただいたサイトを手掛かりに、 もう少し探求してみたいと思います。 また、結果が出ましたらご報告いたします。 OS付属のデバッカには、ばっちしSSE命令が 表示されているので、使えるとは思うんですが・・・。 あ、OSは・・・BeOSなんです。 うわ〜ごめんなさい〜。(?) ITA [2000/04/14 Fri 10:58:07] [210.233.25.3] 最近更新をサボり気味 カトさん、ありがとうございました。 なんとか希望の動作をしてくれました。 その他の皆さん(個人的にメールをくれた人も含めて)、ありがとうございました。 またわからないことがあったら、質問させていただきますので、その時はよろしくお願いいたします。 歩野零一 [2000/04/14 Fri 07:11:50] [210.238.143.85] さかもと様 OSが何かはわかりませんが、こちらが参考になるかもしれません。 http://www.me.ics.saitama-u.ac.jp/~fujita/ http://www.aial.hiroshima-u.ac.jp/~sakai/Linux/gogo2/ SSEはOSが対応していないとダメとも書かれていますね。 ディストリビューションに依存するようです。 Anatrium [2000/04/14 Fri 01:00:38] [210.135.18.220] LinuxやFreeBSDなどのUNIX系のOSのオブジェクトコードの形式、ライブラリファイルの形式や実行ファイルの形式はどのようになっているのでしょうか? NEW [2000/04/13 Thu 19:38:08] [210.251.66.227] >そこでは、MMXなら大丈夫なんですが、SIMD命令を認識してくれま >せん。 >「そんな386命令ないよ」ってアセンブラからエラーが出ます。 SIMDってSSEの間違いかな? SIMDは、Single Instruction Multi Dataの略で、字のごとく、 1つの命令で、複数のデータを扱う命令形態の事を指します。 従って、MMXもSIMD命令の一種です。 SSEは、PentiumIII以降に搭載された単精度浮動小数点のSIMD命令群 で、Streaming SIMD Extentionの略だったと思いますが、これですか? っておいらGCCじゃないからわからんすけど(^^; さかもと [2000/04/13 Thu 18:58:44] [210.174.82.36] 始めまして、さかもとと申します。 (じつは、あまり直接アセンブラとは関係ないのですが・・・。) 私は、GCC(2.9)でインラインアセンブラを利用しているのですが、 そこでは、MMXなら大丈夫なんですが、SIMD命令を認識してくれません。 「そんな386命令ないよ」ってアセンブラからエラーが出ます。 場違いでしたら申し訳ないのですが、 対処法をご存知の方がおられましたら、 情報へのポインタでも結構ですので、ご教授ください。 よろしくお願いします。 K.S [2000/04/09 Sun 22:07:31] [210.238.172.131] Assembly language 質問です。 IBM PC/AT 及びその互換機で広く採用されている「サウンドブラスタ ー」に搭載されているDSP(CT13xxシリーズ)が、Windows において、 8ビットモノラル、サンプリング周波数11.025kHzのPCMデータを扱う 時の、「データチャンク以降のフォーマット」をご存知の方、いらっし ゃいませんか?ここでいうフォーマットとは、テキサスインスツルメン ツのTMSシリーズの「Qnフォーマット」の、CT13xxシリーズ版を知りた い、ということです。よろしくお願いします。 力卜 [2000/04/06 Thu 14:10:51] [192.51.44.12] 間違っていました。ゴメンなさい。 mul dx は、dx(上位16ビット):ax(下位16ビット)に ax * bx の値を代入するのでしたね。 だから、 6: dx = 10; /* mov dx,000ah */ は不要で、 13: ax = ax * dx; /* mul dx */ の前に、 12.5: dx = 10; /* mov dx,000ah */ としなくてはなりませんでしたね。 あと、余白として空白を複数入れていたんですが、 みごとに詰まって表示されますねぇ。 見づらくなってすみませんでした。ではでは。 力卜 [2000/04/06 Thu 13:55:44] [192.51.44.18] ITAさん。 C言語ならバッチリだと思うので、8086のアセンブリ言語のレベル に落とし易いようにCソースで書きました。コメント内に8086用の ソースコードも書きましたので参考にしてみてください。 このサブルーチンの仕様は以下です。 - ds:bxにasciz文字列へのポインタを設定してdec2binを呼ぶ (near call) - 文字列には、文字としては数字(30h〜39h)しか現れないことが 前提になっている(14行目) - 戻ってきたときにはaxに数値が入っている - bx,cx,dxとフラグの内容は破壊される 1: /*dec2bin: */ 2:unsigned short dec2bin ( char *bx ) { 3: unsigned short ax, dx; 4: unsigned char ch, cl; 5: ax = 0; /* mov ax,0000h */ 6: dx = 10; /* mov dx,000ah */ 7: ch = 0; /* mov ch,00h */ 8:label1: /*label1: */ 9: cl = *bx; /* mov cl,[bx] */ 10: bx ++; /* inc bx */ 11: if ( cl == '\0' ) /* cmp cl,00h */ 12: goto label2; /* je label2 */ 13: ax = ax * dx; /* mul dx */ 14: cl &= 0x0f; /* and cl,0fh */ 15: ax += cx; /* add ax,cx */ 16: goto label1; /* jmp label1 */ 17:label2: /*label2: */ 18: return ax; /* ret */ 19:} …もちろん、mov ax,0000h なんかは xor ax,axにした 方がよいとか英字などが出てきたときのエラー処理 があった方がよいとかあるでしょうが、とりあえず 理解しやすいと思われるように簡単に書いてみました。 ではでは。 NEW [2000/04/06 Thu 13:53:14] [210.251.66.227] うーん質問の趣旨が分かりづらいのですが、 > ファンクションコールで外部からの入力を受け付けたときと > いうのは、内部的には文字列としてしか扱われないのでしょうか? > つまり、外部入力を数字として扱うことは可能なのでしょうか? > 現状、「123」という外部入力があった場合、データを保持する > エリアでは、「31 32 33」という文字列として保持されます > よね。これを「7B」として保持する方法をご存知の方いらっ > しゃいますでしょうか? 外部入力というのがまず謎ですが、キーボード等からの入力の ファンクションコールですかね? そのファンクションコールの 仕様がそうなっているなら、それに従うしかないでしょう。 ファンクションの方を改変可能ならば、作り替えてしまえば良い と思います。 123という文字列を数値に変換するのは、入力の数値が10進数なら、 下の桁から順に、10^nしたものと値を掛けて総和を求めれば良い でしょう。この例なら、nの範囲は0〜2(3文字だから)、 一番下の桁は 3 * 10 ^ 0 = 3, 二番目の桁は 2 * 10 ^ 1 = 20, 三番目の桁は 1 * 10 ^ 2 = 100, これの総和は、123となります。 これはアセンブラというより、アルゴリズムの話ですね。 とりあえず、Cが出来るのであれば、Cで書いて、それをアセンブラに するのが良いと思いますよ。 環境にもよりますが、Cの標準関数的なものはアセンブラには 基本的に存在しないと考えて、全て自力で作る覚悟が必要です。 もちろんライブラリやファンクションコールに用意されているなら それに超した事はありませんが、何も用意されていない事はざら ですから。 ITA [2000/04/06 Thu 10:26:13] [210.233.25.3] アセンブラとは関係ない僕の子供のこと はじめまして。ITA と申します。 この度、転職いたしまして、アセンブラをマスターしなければならなくなりました。具体的なCPU名はちょっと割愛させ得いただきます(同じ職場の人が見てたら笑われっちゃう)が、PHSのCPUとだけいっておきます。 今まではC言語でのみプログラムしていたので、アセンブラはまったくの初心者です。それなので、Z80 から勉強をはじめて、やっと今週 8086 まできました。 そこで質問があります。 ファンクションコールで外部からの入力を受け付けたときというのは、内部的には文字列としてしか扱われないのでしょうか?つまり、外部入力を数字として扱うことは可能なのでしょうか? 現状、「123」という外部入力があった場合、データを保持するエリアでは、「31 32 33」という文字列として保持されますよね。これを「7B」として保持する方法をご存知の方いらっしゃいますでしょうか?逆に、16進の数値を10進で外部表示する方法もご存知でしたら、あわせてお教えいただければ、と思います。 一応、過去のログを拝見しましたが、こんな基本的な質問をされている方はいらっしゃらなかったので、今回質問させていただきました。 なお、回答が長くなるようでしたら、メールでも結構です。 よろしくお願いいたします。 歩野零一 [2000/04/05 Wed 22:35:35] [210.251.4.68] NEW様 遅れましたが、レスありがとうございます。 御礼まで。 fnami [2000/04/05 Wed 13:57:53] [202.238.80.25] kakushiさん: >>>AND EAX,imm32 → Clocks 1 >>>AND r/m32,imm32 → Clocks 1/3 >> >>これは、第一オペランドがrのときは1クロック、m32のときは3クロックということです。 >でもなんでわざわざ「EAX」と「r」に分けて表記してある>のでしょうか? >やはり何か意味があると言うことなのでしょうか? AL,AX,EAXをオペランドにする場合にだけ、短い命令エンコーディングが使えるからです。 25 78 56 34 12 AND AX,12345678H 81 E1 78 56 34 12 AND CX,12345678H 短い命令エンコーディングでも、たいていは、実行時間は同じですが、短くなる場合もあります。長くなることもありますが、例外的です。 NEW [2000/04/05 Wed 10:04:34] [210.251.66.227] >それは、クロック数は同じでも、オペコードが違うからだと思いま >す。EAXレジスタを用いた時のオペコードは「26 id」で、そうで >ないときは、「81 id」です。 そのとおりでしょうね。今となっては遺物ですね。 > コードの違い Intel系のCPUは、レジスタの利用方法を特定するという文化の上で 進化して来たので、この様になっているんですね。 nvacaworks [2000/04/05 Wed 00:32:41] [210.131.1.168] nvacaworks to Kakushiさん >fnamiさんのご説明によれば、第一オペランドがr >即ちレジスタのときにAND命令は1Clockということですよね。 >でもなんでわざわざ「EAX」と「r」に分けて表記してあるのでしょうか? >やはり何か意味があると言うことなのでしょうか? それは、クロック数は同じでも、オペコードが違うからだと思います。EAXレジスタを用いた時のオペコードは「26 id」で、そうでないときは、「81 id」です。 kakushi [2000/04/04 Tue 22:14:21] [210.224.140.9] >kakushiさん: > >>AND EAX,imm32 → Clocks 1 >>AND r/m32,imm32 → Clocks 1/3 > >これは、第一オペランドがrのときは1クロック、m32のときは3クロックということです。 皆さん、お騒がせいたしました。 恥ずかしいです… 本当にすみませんでした。 と、謝りながらまた疑問がでました。 fnamiさんのご説明によれば、第一オペランドがr 即ちレジスタのときにAND命令は1Clockということですよね。 でもなんでわざわざ「EAX」と「r」に分けて表記してあるのでしょうか? やはり何か意味があると言うことなのでしょうか? 以上よろしくお願いいたします。 今度も的をはずれていたらどうしよう… fnami [2000/04/04 Tue 19:03:14] [202.238.80.26] kakushiさん: >AND EAX,imm32 → Clocks 1 >AND r/m32,imm32 → Clocks 1/3 これは、第一オペランドがrのときは1クロック、m32のときは3クロックということです。 NEW [2000/04/04 Tue 10:55:25] [210.251.66.227] kakushiさん: >AND EAX,imm32 → Clocks 1 >AND r/m32,imm32 → Clocks 1/3 そのマニュアルを見たわけでは無いのですが、おそらく これは、下が3分の1クロックで終わるというのではなくて、 1〜3クロックかかるって事の様な気がしますよ。 >lea edx, [ecx*4] >lea edx, [esi + ecx * 4] >↑何がどう違うのでしょうか?(爆) >僕の素人的な考えだと下の方が計算量が多くて遅くなるような気が >するのですが… 実際にアセンブルして、コードを見るとわかるのですが、 下の命令の方は小さなコードを生成します。 leaの括弧内は、専用のハードウェアが計算しているらしく、 必ず何かの値を加算する様に出来ている様なのです。 つまり、 lea edx, [ecx*4] と書いても、内部的には、 ecx * 4 + 0 と計算しているわけです。 でもって、この0の部分が即値としてコード中に4Bytesも 埋め込まれます。よって、コードが冗長になるのです。 また、上記の様にハードウェアで一気に計算するため、 遅くなったりする心配はありません。 速度は変わりませんが、コードサイズが小さくなる事で、 もしかしたら、キャッシュにより多くの命令がヒットし、 ループなどで大きな速度差を生み出すかもしれません。 つまり、その命令だけの速度を追求するのではなく、もっとマクロな 視点で考えるのも最適化のテクニックの一つです。 kakushi [2000/04/04 Tue 09:52:47] [210.224.140.9] to NEWさん & 皆さん >32Bit環境で、AXはEAXよりもクロック数(バイト数も)多くなり >ますが、その事ではなくて? >それは初耳というか、そんな事ないはずだけどなぁ。 僕もたぶんないと思うのですが、例のCQ出版の本によれば 例えば「pentium デベロッパーズマニュアル」の「25-31」に AND EAX,imm32 → Clocks 1 AND r/m32,imm32 → Clocks 1/3 と書いてあるのですが… どうなのでしょうか? kakushi [2000/04/04 Tue 09:40:13] [210.224.140.9] 皆さんご親切にありがとうございます。 が、まだいくつか疑問が…(^_^;) to 皆さん 「lea」っていうのは第2オペランドの実効アドレスを 第一オペランドで指定したレジスタに格納する命令らしいのですが、 「レジスタの実効アドレス」って何ですか? to NEWさん lea edx, [ecx*4] lea edx, [esi + ecx * 4] ↑何がどう違うのでしょうか?(爆) 僕の素人的な考えだと下の方が計算量が多くて遅くなるような気が するのですが… また、「出力されるコード」ってなんですか? 以上またしても基本的な質問かもしれませんが、 どうかよろしくお願いいたします。 NEW [2000/04/04 Tue 09:23:28] [210.251.66.227] 失礼しました。INT32Sとか書いてるし(^^; まぁ構造体の中身はなんでもいいんです。 とりあえずサンプルっちゅーことで(^^; NEW [2000/04/04 Tue 09:20:26] [210.251.66.227] mlさん: インラインアセンブラのHELPをみたら、SIZEというCでいう sizeofと同様の動作をするものがありました。 って、対象はVCです。 以下サンプルコードです。 // ### sample structure typedef struct _TMP{ INT32S nTT; char cTT; void* pTT; }TMP; // ### 以下の2命令は同意 __asm{ lea esi, [esi + SIZE TMP] add esi, SIZE TMP } こんなんで宜しいですか? NEW [2000/04/04 Tue 09:11:51] [210.251.66.227] kakushiさん: /*ecxを4倍したものをedxに代入*/ lea edx, [ecx*4] これは本当ですよ。また、これで簡単な掛け算は出来ちゃいます。 シフト命令は、Pentiumの場合Uパイプでしか実行できないとか、 色々あるので気を付けないとね。leaも、この命令で算出された 内容を参照するまで1Clock以上空けないとAGIペナルティ食らう から注意が必要だけど。 それと、おいらは、上記の様なケースでは、シフトを使うかな。 もしくは、0クリアされたレジスタを使って、例えば、 lea edx, [esi + ecx * 4] の様に書く事が多いです。何故ならば、実際に出力されるコードが 非常に大きくなってしまうからです。コードサイズが小さくなれば、 その分だけキャッシュに命令やデータを蓄えられますから、なるだけ 小さなコードにする様においらは心がけています。 >また、その本によると、 >「add」「sub」「and」「or」等の命令で「AXレジスタ」を使うと >他のレジスタを使うよりも >クロック数が多くなるらしいのですが、なぜなのでしょうか? 32Bit環境で、AXはEAXよりもクロック数(バイト数も)多くなり ますが、その事ではなくて? それは初耳というか、そんな事ないはずだけどなぁ。 それから、対象のCPUによっても違うから一概には言えないと 思います。P6系ならば、レジスタリネーミングしているから、 内部的には他のレジスタと何ら変わりない筈だし..。 やすひろ [2000/04/04 Tue 02:17:59] [202.230.246.209] すみません たとえば mov ax,imm と mov bx,imm を たとえば add ax,imm と add bx,imm に 修正させてください。 やすひろ [2000/04/04 Tue 02:13:18] [202.230.246.209] みなさん こんにちは kakushi さんへ >現在僕はメガデモ(っぽいもの)を作っているのですが、 >メガデモでは当然「速さ」が超重要になるので、 >アセンブラで書けるところはアセンブラで書いています。 これはこれでとても楽しいですよね(^^ これを言ってしまっては終わりかも知れませんが最適化の定番なので。 コードを吟味してそれなりの効率アップをできる場合もありますが アルゴリズム的なアプローチから手を入れたほうが手軽に? 劇的な効果を得られる場合が多いかも知れません。 >また、その本によると、 >「add」「sub」「and」「or」等の命令で「AXレジスタ」を使うと >他のレジスタを使うよりも >クロック数が多くなるらしいのですが、なぜなのでしょうか? 最近のx86系CPUは色々なアキテクチャーを持った物が存在するので 私も詳しいことは判りませんが 本に書いてある消費クロック数はあくまでもデコード済みの 実行だけに要する時間だと思います。 少なくてもadd,subなどはオペランドにアキュムレータを含むと 命令名が同じでもコード長が変わってきますよね? たとえば mov ax,imm と mov bx,imm こんなのが全体のスループットに関係してこないのかなぁー? 関係無いかな・・・。 実際にはV-TRUENなど使って計測してみるしかないですけど。 プログラム頑張って下さい。 nvaca [2000/04/04 Tue 01:24:17] [203.104.132.149] The Page of Nvaca to Kakushi それは本当です。というのも、たとえばPentiumの場合では、 インテルのマニュアルによると、lea命令はメモリから32ビットレジスタへのオペレーションでも1クロックですむのに対し、 mov命令は、それだけで1クロックを消費します。当然、後者のlea命令を利用したほうが高速になります。 http://www.csl.sony.co.jp/person/fnami/asm.htm が参考になるのではないかと思います。 また、lea命令は、第2オペランドの実行アドレスを第一オペランドで指定したレジスタに格納します。 なぜAXレジスタが早いのかはわかりませんが、もしそうなら、アーキテクチャ上の問題なのだと思います。 kakushi [2000/04/04 Tue 01:00:02] [210.224.140.9] こんばんは。久しぶりに書き込みます。 と言ってもまた質問ですが… 現在僕はメガデモ(っぽいもの)を作っているのですが、 メガデモでは当然「速さ」が超重要になるので、 アセンブラで書けるところはアセンブラで書いています。 そこで質問なのですが、以下のプログラム /*ecxを4倍したものをedxに代入*/ shl ecx,2 mov edx,ecx よりも /*ecxを4倍したものをedxに代入*/ lea edx, [ecx*4] とした方が遙かに速いというのは本当でしょうか? というか「lea」ってどういう命令なのでしょうか? 一応手元にCQ出版が出している「pentiumデベロッパーズマニュアル」 があるのですが、そいつを見てもよくわかりません。(恥) また、その本によると、 「add」「sub」「and」「or」等の命令で「AXレジスタ」を使うと 他のレジスタを使うよりも クロック数が多くなるらしいのですが、なぜなのでしょうか? というか、なんでこんな仕様なのでしょうか? おそらくなにか意味があってこのようになっているのだと思いますが、 僕はまだ初心者なのでよくわかりません。 以上ながながとなってしまいましたが、 よろしくお願いいたします。 ml [2000/04/03 Mon 17:20:47] [133.9.6.38] NEWさん、レスありがとうございます。 >インラインアセンブラではだめですか? 構いません。是非ご伝授くださいませ。 できれば具体的なコード例お願いします。 なにぬねの [2000/04/03 Mon 13:14:35] [202.224.189.53] SAKURAの季節さん、houbouさん、情報ありがとうございます とりあえずがんばってMASMを手に入れてみます。 あまりに初心者のため、基礎を勉強してからまた質問しにきます。 NEW [2000/04/03 Mon 10:43:47] [210.251.66.227] それから、なんかの最適化の本に載っていましたが、 メモリ転送する際に、場合によっては、転送先の内容が 転送元と同じなら転送しない方が良いという、にわかには 信じがたい現象も起きるんですよね。 とにかく、なるべくバスのトラフィックを軽減してやる方が 高速化には繋がると。メモリが応答する間にCPUは、何命令も 実行できるわけですから、まぁ当たり前と言えば当たり前 なんですが...。 もしSSEが使えるなら、転送関数に入ってきた時に、 prefetch命令を使ってキャッシュにローディングして しまうのも手ですよ。SSEが使えなくても、32Bytes単位に キャッシュへのローディングをしておくと、これまた結構 違いますので、お試しあれ。そうそう、キャッシュバンクの 構成によって、単純に32Bytes毎に読み込むよりはインター リーブ(というのか?)した方が良いCPUもあります。 SSE使うと、命令を入れるだけで10%程度は速くなるので、 とっても楽ちんです。 K6-2以降に搭載されている3D Now!にも同様の命令がありますが、 K6の場合、ひえ列にアクセスする事を想定して、アクセスが あったアドレスの次のキャッシュラインをキャッシュにプレ ロードする機能がハード的に備わっているリビジョンがあって、 あまり意味なかったりします(むしろオーバヘッド分、遅くなります) その機能が搭載されていないCPUは、初期のロット付近なので、 数的には搭載されているものの方が多いでしょう。よって、これは 対応してもあまり意味が無いと思います。 長くなりました。 NEW [2000/04/03 Mon 10:32:44] [210.251.66.227] 歩野零一さん: 一般に、CPUの速度の方がメモリの応答速度よりも高速なんで、 あまり意味無いですね。ただ、おいらは出来る限りMMXを使って ますが...。 rep movs命令も、PentiumII以降で、特定の場合には、高速に 転送できるモードになるらしいですが、実際良く分かりません。 後は、WriteCombine? がどこまで効くのか? とか、 チップセット側のWriteBackが何段あるのかみたいな環境にも 依存してしまうので、なんとも言えないですよね。 MMXで転送しておけば、とりあえず64bit単位ですから、将来的に バスの転送方法などに改変があっても、32bit単位よりは効率が 良くなる可能性が高いかなと思って使ってます。 EMMSのオーバヘッドもまぁ最近は無視できるレベルですし。 また、命令の配置も考えた方が良いですよ。 P6がターゲットなら、4-1-1のμ命令順に配置すれば少しは よくなるかもしれません。P6アーキテクチャでは、メモリに 対しての書き込みは、2μ命令になるので、書き込み後に 読み込み2回配置するのが良いかもしれません。そうすると 読み込みと書き込みの命令数が異なるので、leaなどでポインタを 進める、ループする処理の間にうまく潜り込ませるのも手です。 それと、ループの先頭を32Bytesアラインに揃えるなども一つの 手ですね。それをやっても結果が落ちる場合もあって、なかなか 最適化は奥が深いですが。 おいらは、MMXを使う時、プログラムの制御関係には汎用レジスタを 使って、データにMMX側のレジスタを用いるようにしています。 movdとか、結構厄介な命令だったりするんで(PentiumMMXでは)。 NEW [2000/04/03 Mon 10:16:10] [210.251.66.227] mlさん: インラインアセンブラではだめですか? おいらはC++と組み合わせる時は、全部インラインアセンブラでやってます。その方が色々便利です。(細かい事は出来ませんが) それからスケールファクタは、sizeof(structure)で値を算出して、明示的に加算すれば良いでしょう。というかそれくらいしか方法ない様な気がします。 ml [2000/04/02 Sun 03:44:26] [210.197.78.27] 始めまして、最近アセンブラをはじめて、検索エンジンで このページを見つけて掲示板のログをチェックしながら勉強して おります。アセンブラに関する書籍や資料は少なくてわからない 部分はこのBBSでご厄介になりますんでよろしくお願いします。 早速質問なんですがC++のソースとアセンブラをリンクしようと 思ってるんですがメンバ関数のアセンブラからの呼び方が分かりません。 それからポインタ移動などでは例えばDWORDなら4をスケールファクタ として[.. + 4 * esi]などとすると思いますがサイズの大きい構造体 などの場合はどうすればよいのでしょうか。 過去にもこのような質問がありましたらゴメンナサイ。 どうぞよろしくお願いします。 歩野零一 [2000/04/02 Sun 03:15:08] [210.230.131.48] AZUCO様 レスありがとうございます。 うーん、やはりダメのようですね。オーバーヘッド分くらいは 早くなるか?程度の希望的観測だったのですが。 単純作業ではMMXはなんの意味もないですね。 >X68KのXC ver2等が著作権フリーになりました。 XCまだ持ってますよ。出てすぐに買って、昔えっちらおっちら 担いで帰ったものです。 AZUCO [2000/04/01 Sat 18:38:59] [63.12.69.210] X68KのXC ver2等が著作権フリーになりました。 詳しくは@niftyのFSHARPへ! AZUCO [2000/04/01 Sat 18:36:27] [63.12.69.210] MMXでコピー メモリのリードサイクル自体は変わらないのではないのでしょうか? キャッシュに入るコピーだと速くなるかも? Free-DOS また身売りされてたみたいですね(笑) 歩野零一 [2000/04/01 Sat 12:03:17] [210.238.142.3] いつもお世話になっております。 Cにはmemcpy()という関数がありますが、これをMMXで高速化 出来るかどうか、試しにアセンブラで組んで見ました。 仮にこいつの名前をmemcpyX()とします。 ところが、gprofでベンチマークを採ってみると、素のmemcpy() と処理速度が変わりません。(テストは1MBのコピーを1000回ルー プ) この手の処理速度はMMX、非MMXでも変わらないものなのでしょう か? ;; ;; memcpyX.asm ;; ;; void memcpyX(void *dest, void *src, int n) ;; ;; ;; nasm -f elf memcopyX.asm ;; +16 n ;; +12 src ;; +8 dest n equ 16 src equ 12 dest equ 8 section .text global memcpyX align 16 memcpyX: push ebp mov ebp, esp push eax push ebx push ecx push edx ;; eax -> ebx mov eax, [ebp + src] mov ebx, [ebp + dest] movd mm0, [ebp + n] ; count1 movq mm1, [ebp + n] ; count2 psrld mm0, 5 ; 1/32 count, count1 pand mm1, [mask] ; count < 32, count2 movd ecx, mm0 ; Zフラグは変化するか? and ecx, ecx jz near secondphase loop1: movq mm2, [eax] ;32バイト単位でコピー movq mm3, [eax+8] movq [ebx], mm2 movq mm4, [eax+16] movq [ebx+8], mm3 movq mm5, [eax+24] movq [ebx+16], mm4 lea eax, [eax+32] movq [ebx+24], mm5 lea ebx, [ebx+32] loop loop1, ecx secondphase: movd ecx, mm1 and ecx, ecx jz near epilogue loop2: mov byte edx, [eax] mov [ebx], byte edx inc eax inc ebx loop loop2, ecx epilogue: emms pop edx pop ecx pop ebx pop eax pop ebp ret align 16 mask: dd 31, 0 .end houbou [2000/04/01 Sat 01:43:27] [210.172.148.30] Codename:F お久しぶりです。どもhoubouです。 今まで何していたかというと別に逃げていたわけではなく FreeDOS方面に顔だしていたんでこっちはあまり顔を出せません でした。 あ。そうそうHP仮運営ですが立ち上げました。 多分開発者リンクが皆様のお役に立てると思いますので ご利用下さい。宜しくです。 なにぬねのさんへ チュートリアルなら大量にネットのアップされてますので 探してみると良いでしょう。 それとアセンブラですがフリーで入手できるものとして 有名なのはA86,MASM(DDK,32v5),NASMがあります。 たしか洋書でMASMのフルバージョンが添付されているものが あります。高い($70ぐらい)ので私はしばらくDDKで我慢します。 リンカとかはフリーで手にはいるので。 では。また機会が在ればみなさんお会いしましょう! : |
e-mail: mist@e-net.or.jp | Structured Anchor Tree Return to Menu Return to Parent Menu |
Powered by Unit Missing Link. |