1 :
デフォルトの名無しさん :
02/12/19 20:28
Kぐらいしか使い方知らない・・・
>>1 スレタイは前回となんにも変わらないし、全スレとかいってタイトル違ってるし、
ここは糞スレだな。
>>1 は馬鹿丸出し
VBとかは電気屋で売ってるんだけど、アセンブラはどこに売ってるの?
7 :
デフォルトの名無しさん :02/12/20 15:03
アセンブラ キタ━(゚∀゚)━!! はどうだろう
即死避け
10 :
デフォルトの名無しさん :02/12/21 08:49
>>5 DOS窓開いて
debug
と打て
ヘルプは?だ
抜けるのはqだ
【アセンブラの種類】 ○gas=GNUのアセンブラでGCCにがあればついてくる 形式はAT&T型で慣れるまで読みにくい mov A to B gcc -S hello.c でアセンブラ出力 ○MASM Win32用のアセンブラ。 VCにアドオンとしてもってくるか、MASMの灰色フリーのパッケージがある。 結構使われてたらしい ○NASM Linuxにもはいってることもある優秀アセンブラ 日本語マニュアルサイトがウレシイ ----------------- 結論 gas最強。
Java / C# / Perl なども言語自体が仮想CPUになってるので アセンブラの基本を学ぶことでこれらの造詣が深まること間違いナ死!
>>13 VMで動くって事を言いたいのか?
それなら、Perlは違うだろう。
15 :
デフォルトの名無しさん :02/12/21 12:23
インタプリタとVMを混同してるのか?
>12 > 形式はAT&T型で慣れるまで読みにくい mov A to B プロセッサによりけり。MIPS 系だと inst rd, rs, rt だし。 gas 使う場合には gas 用マクロプリプロセッサ, gasp も合わせて使うと、幸せに なれるぞ。
そういえばNASMの日本語サイトの訳はもう少しなんとかならんもんだろうか。 機械翻訳かはしらないけど、一応顔なんだし。 他にわかりやすく解説してるサイトがいるからいい、と言われればそればそ うなんだけど
アセンブラ アセンブリ アセンブル どれが正しくてどう違うんでつか?。・゚・(ノД`)・゚・。
アセンブリソースをアセンブラでアセンブル
でも最近はアセンブリ言語の事をアセンブラとも言うそうで
石って何?
22 :
デフォルトの名無しさん :02/12/26 23:09
高水準言語に置けるコンパイラと 低水準言語に置けるアセンブラと 同じ関係である。 時としてアセンブリ言語をアセンブラと 呼ぶこともある。
23 :
デフォルトの名無しさん :02/12/26 23:09
↑で良いんだっけ?
>23 良い。っつか、品詞考えれば明白だと思うが。 アセンブラ 名詞 アセンブリ 形容詞 アセンブル 動詞
カタカナ英語で品詞も糞も・・・
間違った用法でもある程度の馬鹿が使えば 辞書でも正当な用法として評価されたりする 馬鹿が新語や新用法をつくっていく 実際現在の言葉も誤用から生まれた物が腐るほどある
>>26 それが文化の真髄だと思われ
フォーマルなものでなく、自由の元にうまれんだよ
まあ言い易いように言い易いように進化してくのが一番なのさヽ(´ー`)ノ
>27 語る前に、言語の変遷を勉強しましょうよ…
なんで文化の真髄になるんだらう
豹変するなんて使うと悪い意味でとられるし 全然あるとか肯定すると言葉遣いが間違ってるとか言われる このあたり既に意味が変わったり用法がなくなりつつある 「ふんいき」は「ふいんき」布団を「しく」は布団を「ひく」とか かなり一般的に誤用されている 平安時代と今で同じ言葉を使っているわけもなく 言葉はこうして変化していくものだが 個人的にはあまり誤用の多い馬鹿には近づきたくないな
Windows2000はOS自体にSSE命令を使ったAPIとか組み込んでないですよね? SPxとかでかっに組み込まれてるのかもしれませんが となるとSSEの機能を生かすにはアプリに組み込むしかないんですよね。
アセンブレ アセンブロ これらは命令形。
馬鹿もここまでいくと手におえんな…。
>>32 どこまでをOS自体のAPIと言うつもりか知らんが、
Directなんちゃらとかサウンド/ビデオコーデックに既に使われとるんじゃないか?
そんなことに関係なくアプリで勝手につかわにゃ生かせないのは同じだがな。
アプリがやりたいことが全部APIに有るわけでもないし。
>>35 それでは明示的にVC6(アセンブラパック適用済)でSSE/SSE2を使うには
インラインアセンブラで書くしかないですよね?
VCがオブジェクトコードとしてSIMD命令やMMXを吐くか?っていうのが聞きたいです。
>>36 コンパイラオプションにそういう指定ないの?
なけりゃ吐かないと思う。
>>36 組み込み関数やインラインアセンブラで明示的に使用しない限り吐かない
SIMD命令を吐くコンパイラはVectorC{PC}しか知らない
いずれにせよスレ違い
ICC の最新版でも吐けるようになったらしいけど
アセンブラァ! - ゴルァの親戚
アセンブレ 鳩サブレの親戚 機械語の味がする
C++のコードをアセンブラで出力したら(g++&cl) わけわかめで笑うしかないんですけど、、、、 なぜこんな複雑なんですか?
45 :
デフォルトの名無しさん :02/12/30 21:22
「はじめて読む8086」買ったけどDUMPすらできない。 探してみたら任意のメモリ間のバイナリ?を表示するのはあったんですけど 本みたいに特定の実行ファイルをDUMPするのはないんですかね。
47 :
デフォルトの名無しさん :02/12/30 21:32
gasどこで勉強しましたか?
>>45 DUMP ファイル名 |MORE
でダメ!?
>>46 使ってみますた。(・∀・)イイですね。
個人的には開始時の女の子の絵が無ければなおいい(w
どうもWindows2000.SP3/KERNEL32.DLに SSE/mmxはくみこまれてるっぽいです $ objdump -d KERNEL32.DLL |grep mm 77e54958: 0f 10 11 movups (%ecx),%xmm2 77e91c92: 0f e9 77 0d psubsw 0xd(%edi),%mm6 ただobjdumpがちゃんと逆アセしてるのかは怪しいですが
>>46 その作者、技術はあるんだろうけど何かキャラが濃いんだよね
紹介する都度、この展開か やれやれ・ オマエラ ほんとニホンジンだねぇ
>>54 その作者、キャラはいいんだけど何か技術が薄いんだよね
>>55 うぉ、情報あるもんですね
できればその絵が使われてるページ教えていただけませんか?
58 :
デフォルトの名無しさん :02/12/31 19:06
今度新しいマシン買うときは 金もないんでDurunにしようと思うんですが GCC関連のコンパイルとかx86系の学習を考えるとセレの方がいいですかね?
MMX にローテート命令がないのがどうしても納得いかん。 punpcklbw とか変な命令はあるのに。
>>58 Duron はもうフェードしてるぞ。
お得な偽皿 XP1700+ にしる。
VC++ 6.0 にプロセッサパックを入れたら「emms がありません」って警告が出なくなった。 まんせー
ギコディウスを
>>46 のツールでDUMPしてたらギコの部分がAAになってたので
そこを書き換えようと思いMS-DOSでDUMPしてたんですが
FFFFより上のアドレスの所はいじれなかったです。エラーになっちゃいます。
これが噂の16bitですか?ヽ(`Д´)ノモルァ
64 :
デフォルトの名無しさん :03/01/03 13:40
IA32の質問です。 適当なバイトコードから、それに対応するインストラクションセットに変換したいとき、 (要するに低機能なdisassemblerを自分で作りたいわけです) 参考にするための資料を教えてもらえませんか?ネットを探しても見当たらなかったので… よろしくお願いします。
67 :
386以降よく判らん… :03/01/05 18:29
winのNASMで、 xchg [ebp],al mov [ebp+1],ah と書いたら不正終了して mov ah,[ebp] mov [ebp],ax に直したら動いたんだが、プロテクトモードの制限か何か?
>>67 xchg [ebp],al
mov [ebp+1],ah
と
mov ah,[ebp]
mov [ebp],ax
は、やっている事が全然違うような気がするけれど・・・
前者のebpとalになにが入っていて
どんなメモリマップになっているのかは知りませんけれど
念のためbyte ptr〜とかも指定してみては。。
>>67 xchg [ebp],al
mov [ebp+1],ah
と
mov ah,[ebp]
mov [ebp],ax
前者は[ebp]のバイトアドレスに対して
元のaxレジスタの内容が[ebp]、[ebp+1]に入るけれど
後者は結局alの下位バイト分しか入っていないのは・・・よいのかな?
ありゃ? xchg [ebp],al mov [ebp+1],al だった… [ebp+1]に[ebp]を移して、alを[ebp]に書き込む処理のつもり。 >68 ちなみにNASMはptr/offsetは無いです。
>>70 こちらはマシン語直打ち環境だけど・・・とくになんの問題もないですねえ。
864500 xchg byte ptr ss:[ebp], al
884501 mov byte ptr ss:[ebp+1], al
8A6500 mov ah, byte ptr ss:[ebp]
66894500 mov word ptr ss:[ebp], ax
デバッガからもコードを追ってみましたが
まったく異常ないです。
>>67 =70
nasm CVS 年末あたりの版をVisualC++6.0SP5+ppのC2.DLLでコンパイルして使っているが特に問題なし
バージョンやオプション特有のバグか、nasm自体のコンパイルに失敗しているのでは?
>>71 さんの言うとおりプロテクトモードの制限ではないので
nasmはずいぶん前にバイナリで拾ってきたもので、 今タイムスタンプ見たら99/6/4 …………これか原因はw
74 :
デフォルトの名無しさん :03/01/07 12:24
X86系でアセンブリソースを最適化できるツールて無いですか? あったら便利だと思うんですけど… 例1 (コンパイラが良く吐くコード) sub eax, 1 test eax, eax jnz short xxx ↓ sub eax, 1 jnz short xxx 例2 (ターゲットにするCPUによって) xor eax, eax mov al, bl ↑↓ movzx eax, bl
>>X86系でアセンブリソースを最適化できるツールて無いですか? それがC/C++コンパイラでしょ? intelのVTなんたらっていうのとか買うしかないのかな? コンパイラがあなたが望むアセンブルを出力するとはかぎらないから アセンブラつかってるんでしょ?
>>75 そういうのを作ったら? 単なる置換ツールと考えたらそう難しくないでしょ
パターンデータをこのスレで募集して皆で育てたりしたら面白いかもね。
IP記録実験
http://qb.2ch.net/test/read.cgi/accuse/1042013605/ 1 名前:ひろゆき ◆3SHRUNYAXA @どうやら管理人 ★ 投稿日:03/01/08 17:13 ID:???
そんなわけで、qbサーバでIPの記録実験をはじめましたー。
27 名前:心得をよく読みましょう 投稿日:03/01/08 17:20 ID:yL/kYdMc
SETTING.TXT管轄でないということは全鯖導入を視野に、か?
38 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:22 ID:rLfxQ17l
>>27 鋭いです。
73 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:27 ID:rLfxQ17l
>ところで、IPが抜かれて何か今までと変わることってあるのでしょうか?
・今までより、サーバが重くなる。
・裁判所や警察からの照会があった場合にはIPを提出することがある。
名スレの予感
まあ別にいいんじゃないの? やりようによっちゃ匿名にはできるわけで、ただちょっと面倒にはなるけど。 ヌー速の糞スレも減るかもしれないし。 ただ誰がログを読めるのかは知っときたいなあ。
だっせ〜フシアナ失敗・・・・
>>76 >コンパイラがあなたが望むアセンブルを出力するとはかぎらないから
そうなんですが、あれば便利だと思って聞いたんですけど
やっぱり無いのかな
>>77 単純なものなら結構簡単に作れそうなんですが
完全にフラグを追いかけたり、命令順を入れ替えたりする事まで考えると
何処から手を付ければ良いのか分からないんですよね…
削除人はIP表示されない悪寒
84 :
デフォルトの名無しさん :03/01/09 14:53
殺人予告でもせん限りIP取られてどうなるもんでもねぇだろ。
ごめん、そんなにおもしろくなかったので寝ます(^_^;)
藪医者ウハウハだな。漏れのIDもだけど。
コピペうざい
>>626 自作PC板も誤爆&宣伝がかなり舞い込んでます
串使ったらええんちゃうんかと・・ って問題じゃないの?
3日で業者のエロいコピペで埋まるのがオチ
__ ) γ´γ~ \ |∞/ 从从) ) __________ W | |┬ イ |〃 / ヽリ.ハ~ ワノ <ろりは全員皆殺しだ | ̄| \ | ̄ ̄ ̄ ̄ ̄|〜 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ◎ ̄ ̄ ̄ ̄ ̄◎ ころころ〜
内部告発やったら自分がただですむわけナイヨ
煽られたら訴えればいいんだね。。。
======2==C==H======================================================
2ちゃんねるのお勧めな話題と
ネットでの面白い出来事を配送したいと思ってます。。。
===============================読者数: 139038人 発行日:2003/1/10
なにやら、連日メルマガだしてるひろゆきです。
そんなわけで、ログ記録実験ですが、いちいちサーバ指定するのが面倒なので、
全部のサーバに入れてみました。
重くなって落ちたりしてもご愛嬌ってことで。。。
んじゃ!
────────────────────────Age2ch─
■この書き込みは、Age2chを使って配信されています。
────────────────────────────
Keep your thread alive !
http://pc3.2ch.net/test/read.cgi/software/1041952901/l50 ────────────────────────────
でもなー訴えるって事は名前ださにゃならんわけで どう考えても奴らに分があるというか 最終的に骨を断たれるというか
(^^)
そうそうこれからあんぐらはnyBBSで はっきりいってまだ実用レベルとは言い難いが(^^;
やろうマルチ・・・
はどこで叩かれた有名人さんだろう?
半角系板では、業者が書き込むとリモホが表示させられてるみたい
肛門から心臓が飛び出そうなくらい怖いです(^_^;)
109 :
デフォルトの名無しさん :03/01/12 00:47
保守age 最近荒らしが酷い
>>109 荒らしというより、スクリプトのバグでは?IP実験を始めた途端に他のスレの
書き込みがPC板全般に流れてきてるみたい。
お前ら、年がバレます
2002年2ちゃんねるアニメランキング1位のアニメに・・・・ モナーが出演決定!!!!!!!!!!!!!!!!!!!!! <<放送時間>> 1/12 大阪 テレビ大阪 (日)9:30〜10:00 東京 テレビ東京 (日)9:30〜10:00 名古屋 テレビ愛知 (日)9:30〜10:00 福岡 TVQ九州放送 (日)9:30〜10:00 札幌 テレビ北海道 (日)9:30〜10:00 岡山・高松 テレビせとうち (日)9:30〜10:00
前スレ上げちまったから こっち上げるぞ。
>>113 ギャラクシーエンジェルに出たのか?
寝てて見なかったけど
>>75 > X86系でアセンブリソースを最適化できるツールて無いですか?
まずないだろうね。
コンパイラが吐くコードを最適化するのは、結局コンパイラが変わったらだめになるし、最近のコンパイラは結構まともなコードを吐くからね。
人間が作成したコードを最適化できるとすばらしいけど、そんな余地はあんまりないだろうからね。
(余地がいっぱいあるぐらいなら、アセンブラなんか使わんだろうし。)
皇太子様のAAが好きだから。
はい。トリップやめました。。(オレも で間違えた・・・) # ちと煽り過ぎたかなとも反省。 で、質問。 今後起こりうる裁判と切り分ける部分って具体的にはどのヘンなのでしょうか?
くすぐり攻撃。 まぁ 火曜日までには、
>>115 出てないよ。
というか、その荒らしにはもう辟易...。
久しぶりに「はじませ」読んだけど V-syncとれとか、割り込みコントローラいじれとか ゲーム作れと言わんばかりの内容なのな。 俺の読み方が偏ってるせいもあるかもしらんけど
122 :
DDKインストールできなかった( -.-) :03/01/13 16:27
DDKインストールできませんでした。 プッププップ、ビープ音が鳴って... MS社に嫌われた。
DDKくらはい
DDKネット上にありました
まじすか MSからは落とせなくなってるんでし
(^^)
128 :
DDKインストールできなかった( -.-) :03/01/13 20:33
DDK別のマシン(シングルCPU)にインストールしたらできました。 どうも、私のデュアルマシンは駄目なようです。
129 :
デフォルトの名無しさん :03/01/14 23:41
(^^)
131 :
デフォルトの名無しさん :03/01/17 21:47
皆は今どんなアセンブラ使ってるんすか? NASM一択なの?
>>131 WindowsならDelphiのインラインアセンブラが一番だな
なに、デルピーってインラインアセンブラも使えたのか。 俺は VC++6.0 のインラインアセンブラだyo
Delphiの便利なのはインラインというかアセンブラ手続きというのを作れる事 で、Cみたいに可搬性を考えなくていいから、最初の引数はEAXで次はEDX と決まってるし(もちろん cdecl にすればスタックフレームも使える) Delphiで書いてDLL作れば他からも呼べて、ホンモノのアセンブラより そこらへんは楽
( ´Д`)/ <16ビット版のNASMをいぢくってたんですが スタックが最低40byteないとバグるっぽいです。 スタックを使わない小さなプログラムでもこれ以下だと暴走するっす。 以上、報告終わり。
>>131 GNU as + gasp
必要に応じて、その上に gcc とか vcl が被る。
>>131 32ビットならNWSA
16ビットならLSICに付属のやつ(正式名は何なのだろうか)
R86 だったか? 漏れは MASM だが。
>>131 昔 wasm + Watcom C/C++
今 Digital Mars C/C++ のインラインアセンブラ
SSE2を使ってプログラムの勉強をしているのですが、MOVSDで下位64ビット に倍精度浮動小数点が渡るんですよね。それで、CMPSDを使って比較をした 後、結果の使い方がわかりません。 結果はディスティネーション・オペランドの下位64ビットに返るわけですが、 それを使って分岐させる方法がわからないのです。 どなたか御指南くださいませ。
掛け算して足し算するんでは?
>>141 xmmレジスタに戻ってきた値にかけ算して足し算するという事でしょうか?
MMXの頃の知識だからどうだかあやしいけど、 計算結果が二通りあって、それらをある条件で切り替える場合、 ・条件の値を0 or 1に変換する ・二通りとも計算する(SIMDの並列性を生かせるとgood) 最後に (条件値) * (結果1) + (1-条件値) * (結果2) を計算すると、望みの結果が得られるという話。 条件値を0 or -1(0xffffffff)にして、 掛け算をbit-andに、足し算をbit-orにするという方法もあるよん。 SSE2見てないからよくわからんが、MMXのころはこうだった。
>>143 なるほど、ありがとうございます。やってみます。
>>140 普通の分岐をしたいのであれば
CMPSDではなくCOMISDを使うとかそういうことではなくって??
146 :
デフォルトの名無しさん :03/01/20 23:06
>>145 そうです!この命令を探していました。ありがとうございます。
COMISDというのか。SSE2命令はどうもニーモニックが紛らわしくて。
147 :
デフォルトの名無しさん :03/01/20 23:13
実際、機械語はどのようになっているんですか? 思うに、XXX.exeが作成されるとAPIコールするという 命令?が羅列されているのでしょうか? また、DLLを参照するようなプログラムはDLL参照命令があると想像します ちなみにネイティブコードとはCPUに依存するというよりOSに依存するという意味で正しいですよね?
>>147 書店に行って Linkers & Loader 買ってきて読め。もし読んでも意味が分からないなら、
その前に勉強することがあるってコトだ。
150 :
デフォルトの名無しさん :03/01/20 23:31
>>148 学生でホビーでプログラムを楽しんでます^^;
まともなプログラムはつくったことがありません><
オープン系といいますか制御、ネット、WEB、DB系のプログラムを
ちょこっとだけ組んでます、、
C言語MASMで組み込んでやったのですがいまいち理解できません
なんでも少しだけかじってます
>>149 英語で書いてなかったらがんばってみます
かなり古いのでしょうか、大きな書店にあるか見てみます
ほぼでよかった もしよかったら専門用語でもよいので2,3行で教えてください
とりあえずどれかOS一つ決めて、とことん調べてみては?
そのようなことを調べるのに資料が多いのはどのOSでしょうか?
今なら日本語リソースが多くて、実物がすぐに使えるLinuxかなあ。 DLLについてはWindowsのほうがスッキリしているかもしれない...
BSDで調べるとしてどの項目から調べるのがよいですか? タスク制御? ヒントをきぼん 一応OSの概要を理解しているつもりだったんだけど だれかリヌのカーネル程度を組めるひといるんだろうか?
あーというかOSを調べてほんとにたどりつくのか? コンパイラを調べたほうがいいのかな? スタティックリンクしてるときはどーしても相対アドレスにCPUが理解できる 命令がはいっているとしか思えない DLLリンクは特定のシステムコールエリアを利用しているとしか思えない ほんとに全然ちがう?
調べれば分かる程度のことを説明するお人よしは あんまりいないと思う
>>157 しかし「充実したドキュメント」とやらら信用できるかというと、イマイチ…
個人的には man page の section 9 が充実してる NetBSD を推すが、147 は
それ以前に MINIX 本でも読んだ方が良いと思われ。タネンバウム先生の
「オペレーティングシステム」って本な。
うひゃあ、予想通りBSD厨登場ッ
自作のアセンブラを作ってみたいと思っているんですけど、 参考にするソースは何が良いですか?やっぱりNASMのソースコード?
>>164 まづは、四則演算をさせらる所からどうぞ
字句解析->構文解析->ラベル解決->配置 みたいな流れを意識しておいた方がいいよ
(^^)
他のプロセスを実行する時、レジスタの内容退避しますよね? デバッグレジスタの内容も退避しますか?
>>167 まっとうなマルチタスクOSなら。
i386系でのFPUレジスタの退避はちと違う。
あるプロセスをデバッグ中に他のプロセスが止まったらこまります
「はじめて読むMASM」って本を買ってきたのですが MASM はどうやったら 手に入れられるんでしょう?
MASMは商品なので買うことになります。 フリーのアセンブラで互換性の高いのなんかあったよね。
とりあえず一通りそろってるやつなら
ttp://www.movsd.com/ でもこれ
> The assembler, linker and some other binary file are the property of
> the Microsoft Corporation and are supplied under the conditions of
> the (EULA) End User Licence Agreements for both the WIN98DDK
> and the PLATFORMSDK.
なんて書いてあるけど、大丈夫なのかな?
>>172 EndUserライセンスと再配布ライセンスを混同した屁理屈
DDKのLICENSE.TXTにサンプルコード以外の扱いが書いていなかったので
都合のいいように解釈して配布しているもよう
大丈夫か否かはマイクロソフトの意向次第だが
敢えてほとんど黒な灰色のものを使う意義は感じられない
と思っていたが読み返してみたところ 98DDKの場合10copiesライセンスなのでやっぱり駄目らしい
どっちにしろプロ向けみたいです。DOS用プリーズ。 MASM32 is not intended as a programming beginners package, it is squarely aimed at experienced programmers who are familiar with windows API programming with compilers and have done some work in assembler. The package assumes that the programmer already knows enough to start working in assembler and is designed with this level in mind. Any programmer is welcome to use MASM32 but unless they have the experience level that is assumed in the design of MASM32, concepts like register sizes to data types, register usage, assembler mnemonics, API calls, calling conventions and other similar technical data will be very difficult to grasp. Programming beginners are better served by learning a higher level language first and when they are familiar enough with the technical concepts involved, they can come back to assembler later.
プリーズあげ。
VCP6Processor Packにはいってるのでは
179 :
デフォルトの名無しさん :03/01/26 15:31
masm.exe index とかで検索すりゃみつかるじゃん
180 :
デフォルトの名無しさん :03/01/26 18:24
韓国に、masm5.x が落ちている罠。
183 :
デフォルトの名無しさん :03/02/03 00:30
日立汎用機Mシリーズのアセンブラについて詳しい書籍はありませんか?
メモリ間コピー専用の 32 バイトのレジスタがあったらうれしいですか? 汎用レジスタとの値の交換や演算は一切できません
というか、汎用レジスタがもっと増えてくれればそれで十分。 64ビット系ではR8〜R15なるレジスタが増えてるラスィので、 早くそれが普通に使える時代になってホスィ。
>>184 それぐらいなら、CPU と非同期に動く DMA 使った方が。
>>187 なんですかそれは?
やっぱり一般の書店では入手不可能なんでしょうかねえ。
>>188 まあ、Mシリーズ (今は、MPxxxx か...) がそこら辺のヤ○ダ電気とかじゃ売ってないからね。
今からMシリーズ買うんなら、日立の営業に電話して「Mシリーズ買うから青マニュアルちょうだい」と言えば OK
どっかにある、Mシリーズ使うなら、そこの運用管理担当者に聞いてみな。
>>190 職場の倉庫みたいなところを探せばMシリーズの機械命令のマニュアルとかあると思うんですけど、
一人で占有するわけにも行かないので、手軽に入門的なことだけでも分かる本があればいいと思ったんです。
営業に電話するって、汎用機のマニュアルなんて個人で入手できるんですか?
191 :
デフォルトの名無しさん :03/02/06 21:19
SH4の命令で次のようなループをアセンブラで書くときどうすればいいの? for(i=0,SUM=0;i<N;i++) SUM=SUM+A[i]*B[i];
>>192 切れ味のいいエレガントな回答にちょっと萌えた。
194 :
デフォルトの名無しさん :03/02/08 09:32
アセンブラ(nasm)でdll作成に挑戦してます。 segment _TEXT use32 public class=CODE align=4096 global ADD1 ADD1: add eax, edx ret export ADD1 ..start: global DllEntryPoint DllEntryPoint: mov eax, 1 ret 12 >nasmw -fobj dll_test.nas は問題ないのですが >ilink32 /Tpd dll_test, dll_test.dll Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Fatal: Error detected (IMP829) Fatal: Warning: インクリメンタル リンクできません。リンクをやり直します Fatal: Error detected (IMP829) Fatal: なんでー? (ALINKを用いると普通にdllができたので、ますます何が悪いのかわかりません)
誰か疑問を解いてーage
教えて君ですみませんが。 cpl = 0 -> cpl 3の切り替えをiretlでやろうと思って、 stackframe : %esp -> %eip %cs %eflags %esp %ss これをbochs上でやると 00003160446i[CPU ] | SEG sltr(index|ti|rpl) base limit G D 00003160446i[CPU ] | DS:002b( 0005| 0| 3) 00000000 000fffff 1 1 00003160446i[CPU ] | ES:002b( 0005| 0| 3) 00000000 000fffff 1 1 00003160446i[CPU ] | FS:002b( 0005| 0| 3) 00000000 000fffff 1 1 00003160446i[CPU ] | GS:002b( 0005| 0| 3) 00000000 000fffff 1 1 00003160446i[CPU ] | SS:002b( 0005| 0| 3) 00000000 000fffff 1 1 00003160446i[CPU ] | CS:0023( 0004| 0| 3) 00000000 000fffff 1 1 00003160446i[CPU ] | EIP=00100404 (00100404) 00003160446i[CPU ] | CR0=0x00000011 CR1=0x00000000 CR2=0x00000000 00003160446i[CPU ] | CR3=0x00000000 CR4=0x00000000 00003160446i[CPU ] ----------------------------------- 00003160446p[CPU ] >>PANIC<< exception(): 3rd (10) exception with no resolution こんな感じで止まります。 ちなみに割り込みから呼び出してるわけではありません。 参考となる情報があったら教えてください。
197 :
デフォルトの名無しさん :03/02/09 06:50
誰か疑問を解いてーage
>>194 exportは使い方が特殊なので
defファイルで指定したほうが簡単です
>>196 Gフラグが立っているので問題ないのかもしれませんが
一見した所、eipがcsのlimitを越えているように見えます
>>198 すいませんでした、ちょっと離れていたので。
このプログラム、a20を有効にした後、1Mbyte以上の領域に転送してから、
しばらくcpl0で実行した後なんですが、
いきなりリミットの制限にひっかかることもあるのでしょうか。
もちろん記述子はcpl0用のと変わらずに、
リミットはフラットモデルに従っていて、dplが違うだけです。
>>196 あとalign=4096は標準OMFでは不正です。
>>199 bochsのlimit表記000fffffがGフラグ適用前の素の値なら問題ありません
>>198 , 200
ありがとうございます。.defファイルを書くことで成功しました。
ilink32は、align=4096を理解してくれるようです。
でも、おっしゃる通りnasmのドキュメントに4096は拡張と書いてあったので、今後256を使います。
しかし今度はALINKでリンクできない…(苦笑)…ソースを共通にすることは無理か…。
不思議なのは、Cで__declspec(dllexport)のように書いて、-Sでアセンブリソースを出力させてみると
その中でエクスポートしている=エクスポート情報が.objに埋めこまれている、ように見えることです。
ALINKがnasmと相性がいいように、ilink32はTASMと相性がいいのかな。
NASMについてお聞きしたいのですが、NASMの展開先とPATH(AUTOEXEC.BAT)設定を以下のようにしても 問題ないでしょうか? この手のソフトで、パス内にスペースがあると正常動作しないものもあると聞いたもので... 展開先 : C:\Program Files\NASM PATH(AUTOEXEC.BAT) : C:\Program Files\NASM すいませんが、何方かご教授お願いします。
SSE2のパック加算命令で adc命令のようにキャリー分を足してくれる命令ってないんだ? 使えねー
>>202 NASMは知らんが普通
"C:\Program Files\NASM"
とするもんじゃないかな。
PATH 設定時は C:\PROGRA~1\NASM じゃないかのう
そもそもnasmはnasmw.exeのみで完結しているから無関係だろう 多分
208 :
デフォルトの名無しさん :03/02/15 05:08
直線描画関数をアセンブラで作れ ゴラァ
drawline: pusha mov dx, line mov ah, 09h int 21h popa ret line: db '----$'
push 0 push y1 push x1 push hdc call dword ptr MoveToEx push y2 push x2 push hdc call dword ptr LineTo add esp, 4 * 7 ret
アセンブラと関係なくてごめんなさい。 ある整数を、4の倍数に切り上げたい。 しかも、元との差分を最も小さくしたい。 これを早く計算したい時は どうすればいいですか? 自分は int x; // <- target // as follows... x *= 3; x += (4 - (x & 03)) & 03; と書いたのですが…
>>211 まちがえました(x *= 3のところはなし)
こう書きました
int x; // <- target
// as follows...
x += (4 - (x & 03)) & 03;
x = (x + 3) & ~3; 最速という保証は全く無し
コンパイラによる そんなときこそアセンブラを・・
> ある整数を、4の倍数に切り上げたい。 > しかも、元との差分を最も小さくしたい。 そりゃ切り上げじゃなくて四捨五入?なんでは
4を法とする整数のceil()の実装の問題。
x = (x+2) & ~3
ここは、アルゴリズムスレでしか?
日本語解読スレです
>>220 >>211 の式ではx=1の時の結果は4ではないかい?
> しかも、元との差分を最も小さくしたい。
これが意味不明だが、1を8や12にするなという事かな
よーするに、四捨五入ではなくて、メモリアドレスかなんかを 4 バイト境界に合わせたりしたいんだろ?
「差分を最も小さくする」というのを解釈すると
0→0
1→0
2→4
3→4
になりそうな気がする(これは
>>218 の式)
>225 でもそれでは”切り上げて”いる事にはならない。
メモリアドレスの境界合せがしたいなら、切り上げでないとおかしい。
え、逆だろ
逆じゃねー
233 :
デフォルトの名無しさん :03/02/23 19:25
あの〜、VC++6.0のプロセッサパックどこでダウンロード出来るでしょうか? 前までMSのサイトで見つかったんですけど…。 今見つからないんです、教えてください。
すごいことになってる…
日本語へんですみませんでした
>>213 >x = (x + 3) & ~3;
これ、いいですね
さっそく使わせていただきます
>>214 >コンパイラによる
>そんなときこそアセンブラを・・
ちなみにアセンブラだと
どうなるのでしょうか?
>>218 >x = (x+2) & ~3
これ、213と違うのですがなぜですか?
>>221 ,
>>222 >ここは、アルゴリズムスレでしか?
>日本語解読スレです
すみません…
>>223 >これが意味不明だが、1を8や12にするなという事かな
はいそうです
つまり、もし増えるとしたら+1/+2/+3の
どれかにしたかったのです
>>224 >よーするに、四捨五入ではなくて、メモリアドレスかなんかを
>4 バイト境界に合わせたりしたいんだろ?
はいそうです
ビットマップです
>>226 >でもそれでは”切り上げて”いる事にはならない。
”切り上げて”にはゼロは含まれていなかったんですね
以下とか未満みたいに難しいです
ごめんなさい…
>>231 >曖昧な仕様に翻弄されてる典型。
ほんとにすみません…
236 :
デフォルトの名無しさん :03/02/26 04:17
>>234 214じゃないけど、例えばER6にある番地がある時、(H8の命令だと)
inc.l ER6
inc.l ER6 ;この3行はmov.l #3,ER5、addl.ER5,ER6より小さく速い
inc.l ER6
and.b #4,R6L で済む。
cで213の展開型は
mov.b #3,R5L
extu.w R5
exts.l ER5
add.l ER5,ER6
add.l #1,ER5
and.l ER5,ER6 この辺がコンパイラが出せる最小の命令です
and.b #-4,R6L でしょ?
あ、ありがと、そのつもりでした。maskはちゃんとHexで書かないといかん(^^;
>>236 アセンブラってよくわかんないけど…
incってincrement?
andってビットのアンド?
後についた.bってもしかしてbitのこと?
ファイルの拡張子(.exeとか)みたいだ
いかにも3足してマスクみたいだ…
extu.wとかextsとかがある下の方は
さっぱりわからんです
>>234 >ちなみにアセンブラだと
>どうなるのでしょうか?
興味本位で聞いたのですが…
興味だけで聞いてもやっぱり
アセンブラはよくわからない
みなさんすごいですね
>>236 >inc.l ER6
>inc.l ER6 ;この3行はmov.l #3,ER5、addl.ER5,ER6より小さく速い
>inc.l ER6
これって
x += 3;
より
++x;
++x;
++x;
の方がはやいということ?
なんか意外だ…
>>240 236のはH8では、ということなので、他のCPUでは
そうとは限らない。
242 :
デフォルトの名無しさん :03/02/27 10:52
アドレス値のシフトや論理積を求めることってどんなことに役立つのでしょ? いまいちその効力が分からないのですが、、、
論理積はアラインメントのときに使うだらふ シフトをすることなんかあるのくわ?
座標値をシフトしてアドレスを出す場合が あるのでは
アドレス値を何かのインデックスとして使う場合もあると思う
データレジスタとアドレスレジスタが分かれている680x0で アドレスレジスタに対して直接演算する命令がadda, subaしかないのも、 アドレス値に対して加減算以外の演算をすることはまずないだろうと いうことなのでは。
石器時代のCPUの命令セットを持ち出されても・・・
以前、SH-3のELFのリロケータブルファイルを展開するときに、 各セクションを配置する際にアラインメントを指定通りにしてあげ ないといけないので、それでやったぐらいかな・・
250 :
デフォルトの名無しさん :03/02/28 08:56
>>245 それは例えば、上位10ビットをインデックスのように
使うということでしょうか?それに対する加減算する
ために、アドレスをシフトするというか。。。
>>250 上位というか、どこか一部分だろうねえ。
253 :
デフォルトの名無しさん :03/02/28 12:55
質問です。C言語で、 struct a { int i char c } v; という構造体があって、 v->i = 4660 //0x1234 v->c = 'm' //0x6d などという処理をする場合、一般にアセンブリ言語ではどのように記述するのでしょうか? #最近高級言語のソースを見てると、内部的にどうなっているのかが気になってしょうがない・・・。もしかして毒されてる?
v->i = 4660; //0x1234 v->c = 'm'; //0x6d (´・ω・`)でした。
>253 構造体のメンバアクセスはベースレジスタ+インデックス指定 でいいんじゃないかな。
>>255 レスありがとう。
例えば二次元配列では、「ベースポインタ+(行サイズ*行添え字)+列添え字」
でそれぞれを引数として渡してやれば、要素のアドレスが得られると思うんですけど
構造体は各々の要素サイズが不定じゃないですか。
要素サイズをどこかに格納しておかなければならないのかな?
>256 構造体の先頭から各要素のアドレスへのオフセットを 「定数」として定義すればよいです。
>>257 おお!何かが見えてきた気がする。
コンパイラの本なんかも読んでみようと思います。
ありがとうございました。
スタックの構造ってどうなってるの? STLのスタックみたいな感じと思って(・∀・)イイ?
>259 LIFO型のバッファなので概念的には似てるけど、中身は当然別物。 スタック領域とpush, pop時に使用するスタックポインタがあるだけなので、 push, pop以外にランダムアクセスだってできる。 また、データの一時的バッファとして使用される以外に、 サブルーチンコールの際の戻り先アドレスや引数を格納したり、 自動変数領域として使われたりもする。
261 :
デフォルトの名無しさん :03/03/04 22:33
axをal,ahに分けて使う場合は一つ8bitになるので 使える値も0〜255ということになりますか?
intの割り算とcharの割り算に 処理速度の差はありますか? それから以下のコードで **Error** div2.ASM(32) Operand types do not match が出るのですが…どうしてですか?
>>262 #include <iostream>
template<typename T>
inline int f(T t) { return static_cast<int>(t); }
template<>
inline int f(int t) { return t; }
int main()
{
typedef char NumType;
volatile NumType x = 17;
volatile NumType y = 5;
NumType q, r;
_asm {
xor edx, edx
mov eax, x
div y
mov q, eax
mov r, edx
}
std::cout << f(x) << " / " << f(y) << " = " << f(q) << "..." << f(r) << '\n';
return(0);
}
>>260 詳しい説明ありがとん。
スタックって偉いね。
>>262 スピードは小さい方が速い。
エラーは読んだとおりだが。
movのオペランドのサイズ一致してない。
マシン語に暗黙のキャストなんかないからな。
alにmovするかmovzxとかつかう。
それよりもdivの使い方調べした方がいいんじゃね?
ついでにidivも調べとけ。
> 265 > スピードは小さい方が速い。 そうですかなるほどなるほど。 > alにmovするかmovzxとかつかう。 > それよりもdivの使い方調べした方がいいんじゃね? > ついでにidivも調べとけ。 アセンブラはわからないのです これもCマガ2001年10月の記事を みて便利そうだなとテストしていたのです どこで調べたらいいのでしょうか… あとNumTypeをintにして-Sでアセンブラコードを 出力したらcdqとかidivとか出てきたんですが これは何をしているのですか?
>>266 符号付きと符号無しで命令が違う。
div=符号無し
idiv=符号付き
コンパイラが勝手にやってくれることをアセンブラでは自分でやらなきゃいかん。
それとバイトで割りたかったら、被除数はax ah=余り al=商
cdqはeaxの値をedx:eaxのクワッドワードに変換する。
ナゼかというと、32ビットで割るときは被除数がedx:eaxになるから。
あれからグーグルで勉強できるところを 検索して勉強しました(すこしだけど) 難しいイメージがあんなにもあったのに どうしてもやりたい欲望があったせいか なんとかはじめることができました すごくうれしい! 感謝です 変更したところは _asm { xor ah, ah // (1) mov al, x // (2) div y mov q, al mov r, ah } です divとidivの違いもわかりました(テストで正どうしなのでdivにした) cdqも意味もわかりました 除算の注意点もしりました ・ゼロで割るな ・結果が格納されるレジスタをこえるな ・割る値を直接かけない(レジスタに入れてから割る)
また(1)(2)のところなのですが、最初は mov ax, x とだけ書いていたのですがまたOperand types... というエラーが出て悩みました (1byte除算なのでaxレジスタにいれているのになぜ) ログをもう一度よんだら「alにmovする…」とあった のでこうしました。 もしかして(1)は不要ですか? (このテストでは不要だが普段は必要とか?) あとmovzxとは?説明をみつけれなかった… ほかにコンパイラにアセンブラコードを 吐かせるとmovszとかもよくみるし…
Intelのサイトへご〜
>>269 mov ax, word ptr x
と書けばいいじゃん。
但し word ptr は x が short の場合に限る。 movzx ax, x (xがcharの場合) でもいい。
今度はループでやってみようとしているのですが 「現在のアドレスの-128〜+127番地以内」 とかいうのがわかりません。 たとえば mov ecx,dword ptr [eax] のサイズはいくらですか? それから @2: mov ecx,dword ptr [eax] and ecx,-16843010 shr ecx,1 mov dword ptr [eax],ecx add eax,4 cmp edx,eax jne short @2 @3: の@2〜@3のサイズはいくらですか?
普通はアセンブラに計算させるもんだが・・・
>>273 気にするな。
shortで届かなかったらアセンブル時にエラー出るから判る。
というか、今時shortとか指定しない。
386以降では条件ジャンプのロング版があるから、ショートジャンプが届かなかったら勝手にロングジャンプにアセンブルされるだろ。
それでは毎回shortをつけてみます >というか、今時shortとか指定しない。 ここ以下がよくわからなかったです 私はbcc32(tasm32)をつかっています -Sでアセンブルコードを出力すると よくshortが付いているのですが、 私が_asm{}のなかで je END としても je short END とは 勝手にしてくれませんでした… shortを付けないと速度で損をしますか? それから、なんだかアセンブラに 慣れてきた気もするので、C/C++で 書いたコード(昔の私のコード)と 速度の比較をしたいのですが… どうやって計測すれば いいのでしょうか? ハァハァしたい…
>je END としても je short END とは そういう最適化は普通はしてくれんだろう。
> shortを付けないと速度で損をしますか? 超タイトなループでかつ運が悪いと損するかもしれないけど 普通はデコードステージで隠されちゃうから見えないと思う
> どうやって計測すれば > いいのでしょうか? > ハァハァしたい… 1000回とか100万回とか適当な回数ループさせて CPU時間を計測するテストプログラムを書くとか。
>>276 timeGetTime()またはQueryPerformanceCounter()
281 :
デフォルトの名無しさん :03/03/09 01:19
>>276 P5以降ならrdtsc命令を使うとか。
但し最近のCPUでは先にCPUIDとか呼んでおかないと、
結果がパイプラインの状態に左右されるよ。
それよか計測部を数千回呼ぶ方が面倒がなくていいかも。
>>276 命令的には386からP6(PenIIIもだ)まで実行時間は同じはずだ。
もっとも、命令単体で速いからと言って、全体で速くなるとも限らない。
速いはずの命令使ったら、そのほうが遅いこともよくある。
命令を選ぶには、アドレス配置とか、キャッシュがどうとか、P5なら命令のペアリング、P6ならマイクロ命令数とかCPUのパイプラインの状態まで考えないとダメ。
ハァハァしたかったらまずループアンロールくらいしろ。
そうしないとコンパイラに負けるぞ。というか、こういう単純な処理で勝つことの方が難しい。
>>277 MASM6でもやってくれるよ。
やらないのはインラインだからか?
TCは常時TASM呼び出しだったが、BCは一応内蔵したんでTASM呼び出しオプションがあったんじゃなかったっけ?
使ってないのでうろ覚えでスマソ。
TASMはパス数を増やせばやってくれる。 普通は1パスだから、やってくれないけど。
ぜんぜんだめだった…ガックシだよ… いや、さ、はかる前から体感できなかったけど… 何が悪いかわからん!教えてください。 目的: __unsigned int64が、32bitレジスタを2つ使って 処理しているようなので、64bitレジスタを1つ 使って処理しようとした(その方が速いと思った) 元のコード: void f0(unsigned __int64 *p, unsigned __int64 *pend, char s8, LARGE_INTEGER *li0, LARGE_INTEGER *li1) { QueryPerformanceCounter(li0); for ( ; p != pend ; ++p ) *p = ((*p) & 0xfefefefefefefefe) >> 1; if ( s8 ) { unsigned int *q = (unsigned int*)p; *q = ((*q) & 0xfefefefe) >> 1; } QueryPerformanceCounter(li1); }
がんばったコード(1/3): void f1(unsigned __int64 *p, unsigned __int64 *pend, char s8, LARGE_INTEGER *li0, LARGE_INTEGER *li1) { QueryPerformanceCounter(li0); _asm { mov ecx, -16843010 /* fefefefe */ movd mm1, ecx punpckldq mm1, mm1 /* fefefefe fefefefe */ mov eax, p mov edx, pend LOOP1: /* eax=p, ecx=mask1, edx=pend, mm1=mask2 */ movq mm0, [eax] pand mm0, mm1 psrlq mm0, 1 movq [eax], mm0
がんばったコード(2/3): movq [eax], mm0 /* (1/3)の最後 */ add eax, 8 cmp edx, eax jne short LOOP1 emms
がんばったコード(3/3): emms /* (2/3)の最後 */ /* fraction */ cmp s8, 0 je short END mov edx, [eax] and edx, ecx shr edx, 1 mov [eax], edx END: } /* end _asm */ QueryPerformanceCounter(li1); }
> movq [eax], mm0 アドレスが8byte alignしてないと怒られるかペナルティかあったような。 あと283の言うようにループをアンロールして複数要素を順次処理する ようにしないと勝てないぞ。具体的には | data[i]:read data[i]:calc data[i]:write | | data[i+1]:read data[i+1]:calc data[i+1]:write | みたいにオーバーラップさせる。 ただ、演算内容が単純だとメモリのread/writeのバンド幅で処理時間が 決まってしまう。この例(andとshiftだけ)はまさにそれに該当する。 ハァハァするのは難しいかも。
>>288 P4 2.8Gでやってみた。
データ数=500000
BCB 5.6
func1 = 23464
func2 = 15576
VC7
func1 = 23335
func2 = 15316
十分速くなってるよ。CPUにもよりそうだね。
P4のメモリが速いからかな。
>>288 のCPUは何だろ。
ま、関数の外で失敗している可能性もある。
しかし、ソフトウエアパイプラインすればまだ速くなる可能性があるのは明らか。
とりあえずmmxレジスタを全部使って書いてみることを勧める。
面白そうだからそのコンパイル可能なソースくれ。
>>290
>>291 #include <windows.h>
#include <iostream>
#define SIZE 500000
void func1(unsigned __int64* p, unsigned __int64* pend, char s8)
{
for (; p != pend; ++p) *p = ((*p) & 0xfefefefefefefefe) >> 1;
if (s8) {
unsigned int* q = reinterpret_cast<unsigned int*>(p);
*q = ((*q) & 0xfefefefe) >> 1;
}
}
void func2(unsigned __int64* p, unsigned __int64* pend, char s8)
{
_asm {
mov ecx, -16843010 /* fefefefe */
movd mm1, ecx
punpckldq mm1, mm1 /* fefefefe fefefefe */
mov eax, p
mov edx, pend
LOOP1: /* eax=p, ecx=mask1, edx=pend, mm1=mask2 */ movq mm0, [eax] pand mm0, mm1 psrlq mm0, 1 movq [eax], mm0 add eax, 8 cmp edx, eax jne LOOP1 emms /* fraction */ cmp s8, 0 je END mov edx, [eax] and edx, ecx shr edx, 1 mov [eax], edx END: } /* end _asm */ }
int prof(void (*func)(unsigned __int64*, unsigned __int64*, char), unsigned __int64* p1, unsigned __int64* p2, char c) { __int64 start, end, freq; HANDLE hprocess; DWORD oldclass; hprocess = GetCurrentProcess(); oldclass = GetPriorityClass(hprocess); Sleep(10); SetPriorityClass(hprocess, REALTIME_PRIORITY_CLASS); QueryPerformanceFrequency((LARGE_INTEGER*)&freq); QueryPerformanceCounter((LARGE_INTEGER*)&start); func(p1, p2, c); QueryPerformanceCounter((LARGE_INTEGER*)&end); SetPriorityClass(hprocess, oldclass); return (int)(end - start); } int main() { unsigned __int64* p1 = new unsigned __int64[SIZE]; unsigned __int64* p2 = p1 + SIZE; char c = 0xff; std::cout << "func1 = " << prof(func1, p1, p2, c) << std::endl; std::cout << "func2 = " << prof(func2, p1, p2, c) << std::endl; }
prof()関数はトリッキーなプログラムスレでどなたかが作って くださったものをそのまま流用しています。コピペで簡単に ベンチマークできるのでとても重宝しています。
よくわからないので仕様一覧という紙の なかからそれっぽいところを書きます モバイルPentium2(233MHz) メモリ64MB(SDRAM SO-DIMM) 増設したメモリ64MB
>>294 私のだと
func1 = 68498
func2 = 69137
でした
あと私のテストコード
#include <windows.h>
#include <stdio.h>
extern void f0(unsigned __int64 *, unsigned __int64 *, char,
LARGE_INTEGER *, LARGE_INTEGER *);
extern void f1(unsigned __int64 *, unsigned __int64 *, char,
LARGE_INTEGER *, LARGE_INTEGER *);
int
main(int argc, char* argv[]) /* ./abc in.bmp out.bmp 0 */
main(int argc, char* argv[]) /* ./abc in.bmp out.bmp 0 */ { HANDLE hf, hh; BITMAPFILEHEADER bfh; BITMAPINFOHEADER bih; DWORD bfhsize, bihsize, hhsize, dw; unsigned __int64 *buf; LARGE_INTEGER li0, li1; if ( (argc < 4) || (! lstrcmp(argv[1], argv[2])) ) return(1); hf = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); ReadFile(hf, &bfh, sizeof(bfh), &bfhsize, 0); ReadFile(hf, &bih, sizeof(bih), &bihsize, 0); hh = HeapCreate(HEAP_NO_SERIALIZE, 0, 0); hhsize = bfh.bfSize - (bfhsize + bihsize); buf = (unsigned __int64 *)HeapAlloc(hh, HEAP_NO_SERIALIZE, hhsize); printf("(%d, %d, %d) = %d\n", bih.biWidth, bih.biHeight, bih.biBitCount, hhsize); if ( bih.biBitCount != 24 ) return(2); ReadFile(hf, buf, hhsize, &dw, 0); CloseHandle(hf);
CloseHandle(hf); /* 前の最後の行 */ if ( argv[3][0] == '0' ) { f0(buf, buf + (hhsize >> 3), hhsize & 7, &li0, &li1); } else { f1(buf, buf + (hhsize >> 3), hhsize & 7, &li0, &li1); } hf = CreateFile(argv[2], GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); WriteFile(hf, &bfh, bfhsize, &dw, 0); WriteFile(hf, &bih, bihsize, &dw, 0); WriteFile(hf, buf, hhsize, &dw, 0); HeapDestroy(hh); CloseHandle(hf); printf("%d\n", li1.QuadPart - li0.QuadPart); return(0); }
>>299 倉木麻衣の壁紙で実行。
P4 2.8G MEM1G WinXP Pro SP1
-- f0 --
(1024, 768, 24) = 2359296
9560
-- f1 --
(1024, 768, 24) = 2359296
9009
サイズが小さいとあまり効果が出なかった。
次に松浦亜弥の大きめの壁紙で実行。
-- f0 --
(2536, 3492, 24) = 26567136
137591
-- f1 --
(2536, 3492, 24) = 26567136
150749
おやおや、遅くなってしまった。多分倉木麻衣の壁紙の方も測定誤差だろう。
>>295 漏れです。使ってくれてありがとう(^д^)
>>302 こちらこそありがとう感謝してます。
もちろん商用には使いませんのでご安心を。
303 :
デフォルトの名無しさん :03/03/10 20:03
ARMの「アーキテクチャリファレンス」とかいうアセンブラのページ (日本語)があったと思うんだけど、アドレス無くしました・・ 検索でも拾えません・・ どなたかアドレス教えてください一生のお願いです
305 :
デフォルトの名無しさん :03/03/11 15:09
みなさんは何のCPUからASM Worldに入っていきました?
それから
>>11 以外にも良いサイトがあったら教えてくだちい
>>305 x86を少し触ってTK85弄ってx86に帰ってきた。
学んだ履歴。 Z80 (PC-8801) ->8086 (PC-9801) ->会社オリジナルの変なCPU1 (8bit) ->会社オリジナルの変なCPU2 (8bit) ->会社オリジナルの変なCPU3 (24bit) ->会社のセミカスタムx86互換CPU1 ->会社のセミカスタムx86互換CPU2 ->会社のセミカスタムSH3互換CPU 一番いやだったのは、会社オリジナルの変なCPU3かな。 24bitつーても、アーキテクチャがマイコンとは言い難い ブツだったのでいろんな意味で特殊だったなぁ。PICがかわ いく見える。 あと、趣味でPIC,AVRなんかも使ってまつ。
>>305 Z80→8086→SC62015→68000→日立の4bit→H8→SH→SX28→8086→H8
なんか抜けてる様な気もするが…こんな感じ。
ちなみにZ80/SC62015/日立4bit/SX28は忘れかけてる。
まー使うこともないだろう。
Z80→8086→80386 かなあ。68000は見ただけ。
310 :
デフォルトの名無しさん :03/03/12 01:48
俺がやったアセンブラはx86,MIPSとTI社のVLIWプロセッサかな… VLIWは性能出すのにかなり疲れた記憶があるなあ
>>305 英語だがPC Assemblerというのが32bitのx86ではいい感じだった。
>>305 IBM 360/370 YHP YEW M6809 i8086 PF/C280 FMR i8085 H64180 i80286
i8751 M68020 Z80 H8/532 三菱50747 NEC75008 三菱3825 H8/338 三菱3825
H8/3434 NEC784031Y H8/3007 Ti/C54x H8/SH2 NEC78C17 H8/SH7050 NEC789026
石のマニュアルのどこ見れば仕事ができるかつきとめるのが速くなったなあ。
>>312 次はTLCS-900あたりを使って、国産ワンチップを制覇して下さい。
>>305 z80/6802/6501 → 6809/8086 → 6301
→ 68000/(DSP みたいな独自プロセサ)
→ 80186/68020 → SH-1 → SH-2 → Pentium
会社で作った独自プロセサは ECL-10K でサイクルタイム 33ns
が目いっぱいだった。今なら、FPGA で...。
316 :
デフォルトの名無しさん :03/03/14 07:35
ちょっと質問です。 VC6で、以下の2つの式をそれぞれコンパイルして、アセンブラ出力しました。 (xは構造体で、aは配列です。) 1) x->r = (x->r == x->a[0]) ? x->a[1] : x->a[0]; ----------------------------------- moveax, DWORD PTR [esi+32] ; x->a[0] movecx, DWORD PTR [esi+8] ; x->r cmpecx, eax jneSHORT $L66838 moveax, DWORD PTR [esi+36] ; x->a[1] $L66838: movDWORD PTR [esi+8], eax ----------------------------------- 2) x->r = x->a + (x->r == x->a[0]); ----------------------------------- moveax, DWORD PTR [esi+32] ; x->a[0] movedx, DWORD PTR [esi+8] ; x->r xorecx, ecx cmpedx, eax setecl leaecx, DWORD PTR [ecx+ecx*4] leaedx, DWORD PTR [eax+ecx*2] movDWORD PTR [esi+8], edx ----------------------------------- C言語のソースでは一見2)の式が単純ですが、 アセンブラ出力してみると、2)の方が命令数が増えてます。 この場合、1)と2)では、一般的にどっちが速いんでしょうか?
317 :
デフォルトの名無しさん :03/03/14 07:36
ありゃ、tabが消えちゃった・・もう一度。 1) x->r = (x->r == x->a[0]) ? x->a[1] : x->a[0]; ----------------------------------- mov eax, DWORD PTR [esi+32] ; x->a[0] mov ecx, DWORD PTR [esi+8] ; x->r cmp ecx, eax jne SHORT $L66838 mov eax, DWORD PTR [esi+36] ; x->a[1] $L66838: mov DWORD PTR [esi+8], eax ----------------------------------- 2) x->r = x->a + (x->r == x->a[0]); ----------------------------------- mov eax, DWORD PTR [esi+32] ; x->a[0] mov edx, DWORD PTR [esi+8] ; x->r xor ecx, ecx cmp edx, eax sete cl lea ecx, DWORD PTR [ecx+ecx*4] lea edx, DWORD PTR [eax+ecx*2] mov DWORD PTR [esi+8], edx ----------------------------------- よろしくお願いします。
318 :
デフォルトの名無しさん :03/03/14 07:40
あ、2)は、 x->r = x->a[x->r == x->a[0]]; の間違いでした。
Pen3,Pen4と仮定して、 条件が偏っているなら前者が速い と思う
486の頃までは 確実に 2)が速い。 以後は、分岐予測がヒットすれば 1)も遜色なくなってきた。 今では、殆ど差が無い。 差が出てもアライメントとかデータキャッシュ関係の差だろう。 命令実行そのものは並列でされるので、キャッシュアクセスに隠れてしまう為だ。
>>319-320 ありがとうございます。
書き忘れましたが、テスト環境はPen3でした。
この式を使う個所は、主にスクリプト言語の述語判定です。
(局所的なfor文などで繰り返し使うわけではない。)
なので、どっちに転びやすいとかいうのは多分無いと思います。
今はジャンプの無い2)で組んでましたが、
実際に測ってから決めることにします。
(leaが遅そうだとか思いこんだりしてました)
ごめんなさい。教えて君させてください。以下のプログラム、多摩ソフトウェアの LASMなら LASM HELLO.ASM LIL HELLO でEXEファイルができるのですが、MASM32だと ML HELLO.ASM LINK HELLO でアセンブルできてもリンクできません。 どうすればよいのでしょうか? assume cs:cseg,ds:dseg,ss:sseg cseg segment start: mov ax, dseg mov ds, ax mov dx, offset msg mov ah, 09h int 21h mov ax, 4C00h int 21h cseg ends dseg segment byte msg db 'Hello !',0Dh,0Ah,'$' dseg ends sseg segment stack db 100h dup(?) sseg ends end start
16bit用リンカが必要
ぐぐって見つけました。 ftp.microsoft.com/softlib/mslfiles/lnk563.exe MASM32/BINにコピーして、コンパイル・リンク HELLO.EXEが出来ました。実行! HELLO! ありがとうございました。さあ、悪いプログラムをガンガン作って世界を征服するぞー!
ストリング命令(REP,MOVS,LODS,...)って 積極的に使うべきなの? あとLEAってなんですか? 便利?
>>325 速度に関係しないところならどうでもいいんでない?
速度に関係するなら常にベンチマークをとるべき。
あと本ぐらいよもう。>LEA
16bit DOSアプリで世界征服か… まあ、気長にがんばれ。
>>328 > まあ、気長にがんばれ。
ダメだよ、急がないと環境がなくなるぞ。
仮想マシンとエミュで生き残るんじゃない?
仮想マシンの世界を征服できてもな・・・(w
まあでも その手の仮想マシンてのは、案外セキュリティは甘いからな .NET とかで破ろうとガンバルより効率いいかもな
16ビットコードはワンダースワン用に転用できるかもな
ワンダースワンも、急がないと環境がなくなるわけだが。。。
まだぷらっとほーむに売ってるかなぁウィッチ
stoswとかstosdとかって、 ediが奇数アドレスをさしているときに 使ってもいいことになってますか?
大丈夫だが386以降はペナルティがドッチャリ付く
>>337 それなら避けられるなら避けたほうがいいですね
stosdのばあい、奇数アドレスではないけど
4で割ったら2があまるようなアドレスだったら
どうなんでしょうか?
やっぱりドッチャリつきますか?
>>338 4byte alignをまたいだらドッチャリ付く。
ああ、ということはrep stoswは二回に一回だね。間違えたスマソ
> ああ、ということはrep stoswは二回に一回だね。間違えたスマソ どういうことかわからないです… 二回に一回とは? あと、何を間違えたのでしょうか?
>>340 rep stoswを奇数番地から始めた場合、
4byte境界をまたぐのは二回に一回という意味でつ
いや、了解してなかった では2回に1回は大丈夫ということ? ペナルティ→大丈夫→ペナルティ→大丈夫…
↑の名前はまちがえました 343を書いたのは342です
実験してみようか。(ベンチマーク厨のお出ましですヽ( ´¬`)ノ) 1,1バイト単位で奇数アドレスから始める。 2.2バイト単位で偶数アドレスから始める。 3.4バイト単位でアラインされたアドレスから始める。 コンパイラの new がどんなアラインを返すのかちょっと調べてから にする。
newが返すチャンクのアラインがよくわからないので、longを確保させて 返されるチャンクを使う事にした。 賢いコンパイラなら、さすがに4バイトでアラインされた先頭アドレスを 返すだろうと勝手に仮定。
ふーループ条件を間違えて、永久ループに入り、REALTIME_PRIORITY_CLASS になっていたため事実上ハングアップしてしまった。WindowsXPでリセットボタン を押すのは初めてだよ。 さて、肝心のループ部分をうpする。 asm { mov ebx, 100 start: mov edi, p cmp byte ptr[align], 0 je label inc edi // 1バイトアライン cmp byte ptr[align], 1 je label inc edi // 2バイトアライン label: mov eax, 0 mov ecx, SIZE cmp byte ptr[mode], 0 jne lword rep stosb // バイト jmp next
lword: cmp byte ptr[mode], 1 jne ldouble rep stosw jmp next ldouble: rep stosd next: dec ebx cmp ebx, 0 jne start } これで、SIZE = 500000で実験した結果を次に示す。
1バイトアライン(BYTE) = 132050 2バイトアライン(BYTE) = 130763 4バイトアライン(BYTE) = 129686 1バイトアライン(WORD) = 412949 2バイトアライン(WORD) = 441081 4バイトアライン(WORD) = 391805 1バイトアライン(DWORD) = 914535 2バイトアライン(DWORD) = 918916 4バイトアライン(DWORD) = 912975 BYTEのSTOSは予想通りアラインの影響を受けない。WORDは2バイト アラインの方が何度やっても1バイトアラインよりペナルティを食う。 どうもキャッシュが関係しているのではないかと思う。 DWORDはアラインの影響を受けないようだ。これは意外だな。
なお測定条件はOS = WindowsXP Pro SP1、CPUはPentium4 2.8G、 メモリはPC2100を使用。 測定結果はOS、CPU、メモリの影響を強く受けると思われるので、 要望があれば全リストをうpする。
バグっていた。 asm { mov ebx, 100 start: mov edi, p cmp byte ptr[align], 2 je label inc edi // 1バイトアライン cmp byte ptr[align], 0 je label inc edi // 2バイトアライン label:
1バイトアライン(BYTE) = 131815 2バイトアライン(BYTE) = 128789 4バイトアライン(BYTE) = 130906 1バイトアライン(WORD) = 451881 2バイトアライン(WORD) = 405049 4バイトアライン(WORD) = 422643 1バイトアライン(DWORD) = 895154 2バイトアライン(DWORD) = 899134 4バイトアライン(DWORD) = 876400 うーん何かよく分からなくなってきた・・・・Pentium4は多分Pentium3とは 全然傾向が違う石なんでしょう。
1バイトアライン(BYTE) = 132450 2バイトアライン(BYTE) = 130877 4バイトアライン(BYTE) = 120831 1バイトアライン(WORD) = 504302 2バイトアライン(WORD) = 457035 4バイトアライン(WORD) = 376032 1バイトアライン(DWORD) = 1002256 2バイトアライン(DWORD) = 1007482 4バイトアライン(DWORD) = 922796 Visual-C++での結果。これなら理解できる。さっきのはBorland-C++。 やっぱりBCCはnewが返すメモリチャンクのアラインがワードか何か なんだろうな。よくわからんけど。
>>353 少し大きく確保して、得られたアドレスを (a + 15) & ~15 とかすればいいやん。
>>354 それいいですね。それでやってみました。
1バイトアライン(BYTE) = 228404
2バイトアライン(BYTE) = 218411
4バイトアライン(BYTE) = 223208
1バイトアライン(WORD) = 438036
2バイトアライン(WORD) = 445308
4バイトアライン(WORD) = 455428
1バイトアライン(DWORD) = 877391
2バイトアライン(DWORD) = 860253
4バイトアライン(DWORD) = 896863
BCCでの結果です。やはり傾向は変わりませんね・・・・
ちなみに
>>355 はデータサイズを10倍にし、ループ回数を1/10にして
います。なぜかというとBYTEを500000回書き込んでも、Pentium4
(Northwood)の場合全部2次キャッシュに収まってしまうので、
それを避けるためにプログラムを変えました。
その結果メインメモリへのフラッシュが発生し、BYTEの結果が約2
倍時間がかかるようになっています。
どなたかPentium3系やAthlonで試していただける方はいらっしゃいま
せんか?その時はソース貼りますので。Pentium4ではアラインの影響
がいまいちわからないのです。
最初に質問したものです いろいろと検証してくださって ありがとうございます 私のはPintium2です コンパイラ(アセンブラ)は bcc32(tasm32)しかありません 試してみたいのですがソースを 貼っていただけますでしょうか?
>>356 stos系などの書き込み時はキャッシュの遅延書き込みが効いてると思われ。
scas, lods, movsなどの読み込みではいかがだろうか?
>>357 遅れました。ソースを貼ります。bcc32でコンパイル検証済みです。
>>
358
やってみます。
#include <windows.h>
#include <iostream>
#include <cstdlib>
#define SIZE 5000000
void func1(long* p, char align, char mode)
{
asm {
mov ebx, 10
start:
mov edi, p
cmp byte ptr[align], 2
je label
inc edi // 1バイトアライン
cmp byte ptr[align], 0
je label
inc edi // 2バイトアライン
label:
mov eax, 0
mov ecx, SIZE
cmp byte ptr[mode], 0
jne lword
rep stosb // バイト
jmp next
lword: cmp byte ptr[mode], 1 jne ldouble rep stosw jmp next ldouble: rep stosd next: dec ebx cmp ebx, 0 jne start } } int prof(void (*func)(long*, char, char), long* p, char align, char mode) { __int64 start, end, freq; HANDLE hprocess; DWORD oldclass; hprocess = GetCurrentProcess(); oldclass = GetPriorityClass(hprocess); Sleep(10); SetPriorityClass(hprocess, REALTIME_PRIORITY_CLASS); QueryPerformanceFrequency((LARGE_INTEGER*)&freq); QueryPerformanceCounter((LARGE_INTEGER*)&start); func(p, align, mode);
QueryPerformanceCounter((LARGE_INTEGER*)&end); SetPriorityClass(hprocess, oldclass); return (int)(end - start); } int main() { long* dsts = new long[SIZE + 16]; long* dst; dst = reinterpret_cast<long*>(reinterpret_cast<unsigned long>((dsts + 15)) & ~15U); // 4バイトアラインにする std::cout << "1バイトアライン(BYTE) = " << prof(func1, dst, 0, 0) << std::endl; std::cout << "2バイトアライン(BYTE) = " << prof(func1, dst, 1, 0) << std::endl; std::cout << "4バイトアライン(BYTE) = " << prof(func1, dst, 2, 0) << std::endl; std::cout << "1バイトアライン(WORD) = " << prof(func1, dst, 0, 1) << std::endl; std::cout << "2バイトアライン(WORD) = " << prof(func1, dst, 1, 1) << std::endl; std::cout << "4バイトアライン(WORD) = " << prof(func1, dst, 2, 1) << std::endl; std::cout << "1バイトアライン(DWORD) = " << prof(func1, dst, 0, 2) << std::endl; std::cout << "2バイトアライン(DWORD) = " << prof(func1, dst, 1, 2) << std::endl; std::cout << "4バイトアライン(DWORD) = " << prof(func1, dst, 2, 2) << std::endl; delete dsts; }
lods、SIZE=5000000×10回でやってみた結果です。 1バイトアライン(BYTE) = 277337 2バイトアライン(BYTE) = 268935 4バイトアライン(BYTE) = 269434 1バイトアライン(WORD) = 421938 2バイトアライン(WORD) = 280317 4バイトアライン(WORD) = 280200 1バイトアライン(DWORD) = 474518 2バイトアライン(DWORD) = 450938 4バイトアライン(DWORD) = 367506
>>361 1バイトアライン(BYTE) = 565462
2バイトアライン(BYTE) = 564352
4バイトアライン(BYTE) = 506370
1バイトアライン(WORD) = 1063233
2バイトアライン(WORD) = 1014034
4バイトアライン(WORD) = 1014949
1バイトアライン(DWORD) = 2097202
2バイトアライン(DWORD) = 2017584
4バイトアライン(DWORD) = 2034207
このような結果になりました
どう評価すればいいのでしょうか?
アライメントの影響はないということ?
>>363 ありがとうございました!そうですね、ライトバックキャッシュが効いているので
あまりアラインの差は出ないようです。今からlodsのfunc貼ります。これならかなり
差が出るでしょう。
void func1(long* p, char align, char mode) { asm { mov ebx, 10 start: mov esi, p cmp byte ptr[align], 2 je label inc esi // 1バイトアライン cmp byte ptr[align], 0 je label inc esi // 2バイトアライン label: mov ecx, SIZE cmp byte ptr[mode], 0 jne lword rep lodsb // バイト jmp next
lword: cmp byte ptr[mode], 1 jne ldouble rep lodsw jmp next ldouble: rep lodsd next: dec ebx cmp ebx, 0 jne start } }
後からmovsもやってみます
movsの結果です。BYTEとWORDがアラインの影響を強く 受けているのはなぜなんでしょうか? 1バイトアライン(BYTE) = 421525 2バイトアライン(BYTE) = 389473 4バイトアライン(BYTE) = 309287 1バイトアライン(WORD) = 1019163 2バイトアライン(WORD) = 637366 4バイトアライン(WORD) = 617137 1バイトアライン(DWORD) = 1293675 2バイトアライン(DWORD) = 1250312 4バイトアライン(DWORD) = 1244611
(dsts+15)だと、dstsがlong*なので実アドレスはdsts+15*4になりませんか? 先にdstsをバイトポインタに変換しないとまずいのでは。 この部分は保険ですから結果に影響はないかもしれませんが。。 あと、movsの場合は、転送元と転送先がキャッシュの同じラインに 格納されるか("破壊的"か)どうかも結果に影響すると思います。 キャッシュのブロックサイズや連想度等を考慮して転送アドレスを 調整すれば、結果が変わるかもしれません。
アラインテストの上のコード、転送以外のコードのオーバーヘッドが 気になったので、BYTE転送、WORD転送、DWORD転送にわけて アライメントは呼び出し時にそれぞれ dst+1, dst+2, dst と 1MBの転送時間を計測するように書き直してテストしてみた。 cmps?, movs?はsrcとdstを256バイトずらして破壊的にならないようにした。 結果。 Pentium III (x86 Family 6 Model 8 Stepping 6, GenuineIntel)では 読み込み系(lods?, scas?, cmps?) などはアライメントにほぼ影響なし。 DWORD境界DWORD転送を 1.00 とすると BYTE境界DWORD転送で1.10 DWORD境界WORD転送で 1.23、BYTE境界WORD転送で1.36 DWORD境界BYTE転送で 1.75、BYTE境界BYTE転送で1.74 つまり 読み込み時のアライメントの影響はあまりないが WORD読み込みは DWORD読み込みより 30%前後遅く BYTE読み込みは DWORD読み込みより 75%前後遅かった。 書き込み系(stos?, movs?) は全テストにおいてほぼ同一値。 転送単位、アライメントに関係ない結果に。。。
上記と同じプログラムでL1 Cacheに収まる範囲内のメモリアクセスを ためしてみた。(= 64KB) 結果。 Pentium III (x86 Family 6 Model 8 Stepping 6, GenuineIntel)では 読み込み、書き込みに関係なくほぼ同じ傾向が出た。 DWORD境界DWORD転送 を 1.0 として WORD境界 DWORD転送 が 4.2 BYTE境界 DWORD転送 が 4.6 DWORD境界WORD転送 が 2.0 WORD境界 WORD転送 が 5.0 BYTE境界 WORD転送 が 5.5 DWORD境界BYTE転送 が 2.0 WORD境界 BYTE転送 が 9.5 BYTE境界 BYTE転送 が 9.7 WORD境界やBYTE境界はペナルティがどっちゃりつくという予想通りの結果。 L1 Cacheを超える場合はあまり関係ないということになるな。
>>370 rep movsとかrep stos一命令だけで全コードの99%以上の実行時間を
占めるので、他のコードのオーバーヘッドなんか関係ないと思うのだが。
>>371 そんなに差が出た?ペナルティがどっちゃりだと言っても最高4倍ほど
しか付かないように思うのだが。多分キャッシュのラインの関係もある
んだろうね。
> 最高4倍ほど 充分ペナルティだと思うが、どうか。
>>366 遅くなりましたが2番目の
実験コードの結果です
1バイトアライン(BYTE) = 1302662
2バイトアライン(BYTE) = 1275674
4バイトアライン(BYTE) = 1275531
1バイトアライン(WORD) = 2065923
2バイトアライン(WORD) = 1662876
4バイトアライン(WORD) = 1662833
1バイトアライン(DWORD) = 3121135
2バイトアライン(DWORD) = 3094505
4バイトアライン(DWORD) = 2721193
>>374 lodsの場合はライトバックキャッシュの代わりにプリフェッチ機構が働く
ので、結果が変わってくると予想されますが確かにそのようになって
いますね。
結果的にはPentium4とPentium3はそんなにペナルティの傾向に差は
ないようです。
>>371 さんはL1キャッシュに限定しているから、「素の」CPUのペナルティ
を測ることができたようですね。Pentium4はトレース・キャッシュという
怪しげなキャッシュを使っていますが、一応データもキャッシュできると
仮定して、L1に乗るようなプログラムを走らせてみました。
1バイトアライン(BYTE) = 167753
2バイトアライン(BYTE) = 167779
4バイトアライン(BYTE) = 48657
1バイトアライン(WORD) = 293953
2バイトアライン(WORD) = 173335
4バイトアライン(WORD) = 52731
1バイトアライン(DWORD) = 431089
2バイトアライン(DWORD) = 431042
4バイトアライン(DWORD) = 76308
てな感じでやはりアラインはL1キャッシュ内だとすごく大きく効いてきますね。
376 :
デフォルトの名無しさん :03/03/20 17:50
NASMアセンブラで アセンブラを記述するにはどうすればいいのでしょうか?
db 'アセンブラ',0
L2キャッシュの有り難みが今までイマイチわからなかったが、 実はアラインの問題をかなりの程度まで解決してくれるのか・・・・
誰かまともに答えてください。
>>376 アセンブラでアセンブラ記述する ?
エディタでしこしこ書けば OK
383 :
デフォルトの名無しさん :03/03/21 00:52
PUSH GR3 ってか?
>>376 とりあえず、君がまともに質問することが必要だと思うが(w
おそらく誰も質問の意味を理解できていないぞ。
もしかして構文がわかっていないだけなのか?
アセンブラを使って アセンブラを作りたいのかな キチ○イか神になるからやめておけ
もう春ですね
388 :
デフォルトの名無しさん :03/03/21 15:18
>>i386
おめでと、386の地雷を踏みました。
>>382 glibcとか使えば比較的楽かもね。
でも、ほんとにキチ○イか神にでもなってしまうぞ。
>>388 でも昔の何人かのきちが・・・おっと神はやってのけたんだよなー
つーかアセンブラもなかったころは機械語直接書いてアセンブラをつくったんだろうな・・・ 今よりは単純だったとはいえ・・・ハァ・・・
>>386 6809を使ってた頃は1パスアセンブラをアセンブラで書いたものだよ。
2パスアセンブラはさすがに頭が爆発して無理ですた。
ハッシュなんか機械語で実装するのは事実上無理ぽ・・・・・
>>391 ならそのアセンブラで実装すりゃいいじゃな
というか1パスという事はラベル解釈しないアセンブラって事だよね?
>>392 そう。一行アセンブラ。だからほとんど使い物にならない。
もちろんこれをファイルから読み込ませるように改造すれば、
ラベルの使えないアセンブラができるわけだけど、ラベルが
使えないという事はジャンプもテーブルも使えないわけで、
使い物にならない。
でもちょっとしたコードをいちいち本を見てハンドアセンブル
する手間が大幅に省けたよ。
>>394 optasmもフルアセンブラだったような・・・
マクロは超強力だったなぁ・・・・
tasmも、一応1パスという話だったと思ったが。
ただ1パスだとジャンプがshortでできる場所も、みんな
nearになったり、無駄な場所にnopが埋め込まれたりする。
396 :
デフォルトの名無しさん :03/03/21 23:43
tasmはパス回数指定可能。嘘書くな厨房め
>>392 >>395 も書いてるとおり、1パスでラベル使えるアセンブラは、いくらでもあったよ。
アドレスが確定しない所は、領域だけ空けといて確定したら埋め込めばいいだけ。
オンメモリで全部処理しておもむろにファイルにオブジェクト吐く奴とか、埋めるべき所とその値のテーブルをファイルの最後にくっつけてリンカやローダに「あと、よろしくね」という無責任野郎な奴もあったね。
アセンブラで書けたら「神」とか言ってる奴いるけど、ほんの15年ぐらい前は当たり前だったし、アセンブラだってサブルーチン/ライブラリが使えるんだから、そんなに言うほどのことではないよ。
>>396 あぁ、「可能」という文字が抜けてたか。
そりゃ、複数指定できるのは知ってるさ。普段はtasmを使ってるからな。
鬼の首取ったように、わざわざageて書く程度のことでもあるまいに(w
>>376 盛り上がる話題を提供してくれたのでチョット協力。
1. どのCPUのアセンブラを書くか決める。
2. CPUのレジスタの表記法を決める。
3. CPUのオペコードに対応するニーモニックを決める。
4. オペランドのアドレッシングモードに対応する表記法を決める。
5. ラベルの表記法(スコープも含む)を決める。
6. 必要な擬似命令(マクロを含む)を決める。
7. 字句解析ルーチンを設計。
8. 構文解析ルーチンを設計。
9. シンボル管理(ラベルなど)方法を決める。
10. バイナリーのフォーマット(リンカに依存)を決める。
11. コード生成ルーチンを設計。
12. アセンブル、実行、デバッグ、仕様変更を根性の続く限り繰り返す。
>識者様、抜けている所や間違いを補足してね。
EBXレジスタって、EBPレジスタと 何か関係があるのでしょうか? -Sでアセンブラコードを出力すると 関数の最初と最後のあたりで よくpush/popしているようでが あと、レジスタの汎用度の順番 (気楽に使える順番)をしりたいです。 自分は今、 EDI > ESI > ECX > EBX > EAX > EDX だと思ってます。 そして ESP, EBP はふれないようにしています。
中途半端にアセンブラを触ってみて 引数なんかのスタックに直でアクセスするのに BPとBXが無いと辛かった気はするのだがなんでだったか忘れた。
BX は BPと同じくベースポインタに使える4つの一つだったので、 オブジェクトポインタにEBXが使われてるのでは? 演算用には EAX:EDX,ECX, を使うの普通では? EDI,ESI,EBP,EBX は保存してから使うのが普通 EBPはスタックフレーム(ローカルレジスタ・引数アクセス)に使うのが普通
>>401 BPはデフォルトのセグメントがSSなので、スタックフレーム
にアクセスするときにセグメントオーバーライドしなくてもOKという利点が。
だからスタックフレームアクセス専用と考えておいていいね。
BXはDSだけど、二次元配列にアクセスするのに [BX+SI+xx]とか
できるんだよね。[SI+DI+xx]は無理(たしか)。
LSI-Cだと引数や返し値にBXとか使ったりして特殊(w
tasmなんかと組み合わせて使うときは面倒だね。
ARG疑似命令とか使えないし。素直に腐ったr86使えってこと
なんだろうけど。
なるほど、ためになります。 LSI-Cでなんか思い出してきました。 intdos()じゃダメなDOS Callをアセンブラで書いて LSI-Cのソースとリンクさせようとして居たような気がする 引数AX〜DXまで順番に割り当てられるんですよね 引数が少ない内は結構使いやすいんですが 引数のが4個以上になると汎用レジスタ埋まっちゃって 他のレジスタは基本的に破壊禁止だからpushするしか身動きとれない。 それでどっかのレジスタをプッシュすると こんどはSPの値が-2されちゃうという具合で単純にpush とpopだけでは スタックに積まれた引数まで取り出すことができなかった それで push ax mov ax,[sp+4] みたいなのを試みるもなぜかできなかったようなきもする。 それでLSI-Cが-Sオプションで吐き出すアセンブラをみながら なんとなくBPを使うのかなあと思ったところで 面倒くさくなってアセンブラの勉強を止めました。 もしかしてmov ax,[??+4]みたいな使い方のできるレジスタが ベースなんですかねえ。
80386以降はほとんどのレジスタをベース・ポインタとして使えるように なったのでとても使いやすい。命令の対称性が高まったためだと 考えられる。しかしレジスタの少なさは相変わらずだったね。 PentiumPro以降でレジスタ・リネーミング機構を内蔵したためレジスタ の依存関係に起因するストールの確率が減ったが、プログラマが その事を意識しつつアセンブラで書くのは不可能に近い。 内部的にはRISC(μops)で動いているので、μopsの数を減らすような 命令を優先的に選択してプログラムするとパフォーマンスが上がるが、 プログラマから見れば単調な命令を繰り返し書いているように見え、 あまり面白くない。
MMXだと8バイトまとめてコピーできますが SSE使えば16バイトまとめてコピーできるんですよね? ビットマップなどの画像のピクセルデータをコピーするときに MMX使ってますが同様にSSE使っても大丈夫でしょうか? 以前どこかでSSEでコピーするのは良くないやらなんやら聞いたもので もしできるのであれば単純に2倍近い速度になって助かるのですが・・・
>>406 実際やってみたらいいと思うが。
2倍どころか全然変わらん予感がする。
>>407 それはメモリアクセスのレイテンシのせいか?
キャッシュ内に収まっている場合はかなり高速化すると思うが、ビットマップじゃ収まらないか
>>409 アーキテクチャにもよるかも知らんが、最近の CPU はバス幅は関係ないぞ。
CPU 内部の L2 キャッシュ外の領域が要求された場合、その領域のデータは
32bytes 単位で内部キャッシュに転送され、レジスタに読み込まれる。
↑ キャッシュラインは 32bytes とは限らんな。 Pentium 4 では 128bytes だし
キャッシュライン全体が埋まると同時に利用可能になるというわけでもなかったような メモリバスから読み込んだ分が順次利用可能になっていくCPUもあった気がする
Pen3,Athlon?Pは128ビットSSE命令は 内部で64ビットμops命令x2に分割してから実行する。
以下の各ルーチンで 1GB のメモリコピーに要する時間を測定してみた。 (1) memcpy test : memcpy 関数を使用 (2) MMX test : movq を使用、ループアンロール 4 回 (3) SSE test : movaps を使用、ループアンロール 4 回 ソース、デスティネーションのアドレスは、128bytes でアラインメントしてある。 環境 : VC++ 6.0 SP5 + Processor Pack, 実行速度最適化 Athlon XP 1666MHz, AMD 761, 266MHz DDR-SDRAM 512MB, Windows XP ・src, dest それぞれ 8KB の領域、128K 回繰り返し memcpy test : 260ms MMX test : 180ms SSE test : 170ms ・src, dest それぞれ 64KB の領域、16K 回繰り返し memcpy test : 560ms MMX test : 461ms SSE test : 431ms ・src, dest それぞれ 512KB の領域、2048 回繰り返し memcpy test : 3455ms MMX test : 2764ms SSE test : 2744ms ・src, dest それぞれ 4MB の領域、256 回繰り返し memcpy test : 3435ms MMX test : 2794ms SSE test : 2754ms 少なくとも Athlon XP では、キャッシュ内においても MMX から SSE にした場合メモリコピーは速くならないようだ。 ちなみに、GetTickCount で計ったからあまり精密な値ではない。
>>414 乙〜
コピーするならMMXで十分ということで
ファイナルアンサー?
んー結局P3、P4系のCPUはデータバス幅が64bitなので、SSE128ビット を使って転送しても結局は64ビット×2回の転送になるのでそんなに 速くならない、そういう事かな?
>>416 データバスというよりロード/ストアユニットかな?
P4のロード/ストアユニットはP3と違って128bitなので、 SSE128ビットの方が速い。
>>414 なんで8KB×128Kがダントツで速いんだ?
本当に4MBx256の13倍以上も速いのか?
>>419 同じ8KB領域への連続読み書きだと完全にL1キャッシュにヒットするからでしょ。
64bit266MHzDDRSDRAMの性能と
64bit×2本1666MHzL1キャッシュメモリの性能差。
予想通りの結果だね。 確かP4でもSSE movapsの方がレイテンシもスループットも倍だたんだよ。 413の言うことがP4でも当てはまるんだろうね。 ちなみにスループットでMMX 1クロックSSE 2クロック。 それで転送しかしてないんだから、メインメモリのレイテンシを隠しようがない。
>>421 P4は、movapsによるメモリアクセスはスループット1クロックだよ。
C++の名前空間がからんでいる場合の データ転送の書き方をおしえてください。 namespace A { // Aという名前の名前空間 int a; } namespace { // 名前なし名前空間 int b; } void f() { _asm { // ここで、eax に A::a を mov する // ここで、ebx に b を mov する } }
処理系に激しく依存すると思うが。
>>424 BCCとかでは using namespace A; とやって a を外に出さないと
だめみたい。
>>414 memcpy,movq,movapsでPentium4でやってみた。
16バイトアラインメント、Pentium4 2.8G、PC2100、WindowsXP
SIZE=5000000バイト
memcpy = 52655
MMX movq = 30186
SSE movaps = 29940
Pentium4でもMMXとSSEの差はほとんど出ていない。
私はbcc32(tasm32)しかありません C/C++ の union や bitfield について、 アセンブラは、これらをレジスタに使うかどうかに 消極的なのでしょうか? たとえば、uchar*2 を ushort*1 にパックするには mov al, c0 mov ah, c1 で済むので、そうなるように期待して union X { unsigned short ushort; struct { unsigned char low; unsigned char hi; }; }; x.low = c0; x.hi = c1; と書いても、レジスタを使わずに スタックを使っているようなのですが…
PentiumProとか2とか3とかではペナルティがもっさり付くよ 避けるのも無理はない
>>428 unionに限らず、structやclassを使ってもレジスタを使ってくれない。
常にthisを通したアクセスにするようだ。C++でなくてもCモードで
コンパイルしても「隠れthis」があるようなコードを吐く。
コンパイラは?
>>431 BCC32だとそうなる。VC++.NETではthisポインタが必要ない時は
そのような面倒なコードは吐かないようだ。
でもVC++.NETでもunionはレジスタを使ってくれなかった。
ここは良スレだなぁ。 アセンブラだから下手な厨も寄り付けないからだろうな。 ほかの言語スレはひどいありさまだ…。 # sage
誰か無知な漏れのために 「アラインメント」が何なのか説明してくださいまし
アセンブラで ALIGN というと、命令やデータをその位置を何ワード毎に配置するかの設定の事 最近のCPUではループ負荷が配置の差によって数割変わる事も多く、 小手先の高速化手法よりアライン調整(単にNOPを入れるだけだが)の差が大きい
>435 ひとつ賢くなりますた、thx!
VC++の最適化でアラインメント調整とかしてくれてますかね? さすがにそこまでは無理かな
struct は #pragma pack しないと勝手にパディングするけどな。 データ領域もアラインされてる。 コードはL1キャッシュが効くから下手にnop入れるほうが返って遅い。
VC++6.0だと4byteでアラインされるね
441 :
デフォルトの名無しさん :03/03/31 22:16
>>438 してるに決まってんだろーがゴラァ
一からやり直し
もうアセンブラだけで作る時代は終わったね。 アセンブラでAPI呼ぶ人ももういないでしょ。 どうしても必要なとこだけ関数の一部を置き換えるくらい。
>>441 つか、構造体メンバのアラインメントはしてあって当然だっての。
そのための設定項目も存在するってのに
>>444 つーか、
>>437 の聞き方が良くない。
最適化によって「自動的」にアライメントを調整するか ? と言うなら No.
あらかじめ設定したアライメントに自動で調整するか ? と言うなら Yes.
私はアセンブラは 画像の処理速度を高速にするのと エロゲー画像の吸出しツールとかを作るときに 使うのぐらいかな・・・?
ho
bcc32を使っているのです 逆アセンブラというのを使ってみようと 思ったのですが、何を使えばいいですか? そしてそれはどこにありますか?
a = b>c ? d : e を↓のように分岐使わないコードを吐くコンパイラって ないですか? mov eax,b cmp eax,c mov ebx,e cmovg ebx,d mov a,ebx
gcc ただし、cmovは必ずしも速いとは限らないことにご注意。
>>451 それって d,eが普通の変数ならいいけど、 そうじゃないと両方評価してしまうから
良くないかも
mov eax,b cmp eax,c cmovg eax,d cmovle eax,e これならレジスタも使わないし、評価もCの要件を満たすから いいんじゃなかろうか。
しもた mov a,eax を最後につけてね。
SIZE=5000000、16バイトアライン、Pentium4 2.8G、PC2100、WindowsXP Pro SP1 でやってみた。 cmov = 106988 cmp = 202720 cmovの方が2倍ほど速かった。std::rand()を代入している配列で比較したので 分岐履歴テーブルが働かない状態なのでパイプラインストールが発生している のだろう(cmpの方)。
bとcに相関性があれば、jcc使った方が速い場合もあるとおもう。 cmovのレイテンシってでかいよね。 VC6++でもsetccを使って分岐コードを排除してた
>>458 配列に全部 1 を入れてみた結果。
cmov = 106287
cmp = 81764
配列に1、2、3、4と 1 を入れてみた結果。
cmov = 107042
cmp = 90303
確かに配列に何らかの規則性があり、BTBが有効に働く場合は
jccの方が速いようだ。
461 :
デフォルトの名無しさん :03/04/10 18:17
Σ(゚Д゚;
462 :
デフォルトの名無しさん :03/04/10 19:20
463 :
デフォルトの名無しさん :03/04/11 22:50
関数の頭で subsp,#0x0c のようにスタックポインタを後退させて ↓のような感じで strr0,[rp,#0x00] ldrr0,[rp,#0x00] スタックを使っているソースを見たことがあります。 この方法で沢山の数値を保存できるとは思うのですが スタックは無限ではないので↑のように 勝手にスタックポインタを動かすことに抵抗があります。 そういえばpush/popをするとき スタックの限界なんて意識するひとはいないようですが それが原因でバグがおきたなんて話しも聞いたことがありません。 一体どうしてなんでしょ?
>>463 環境によっては、あふれて挙動不審になります。
そういうことを気にしなくてもいいのは、
足りなくなると適当に割り当ててくれるから。
>>463 組み込みでは厳密にスタック消費量をみるのが普通ですよ。
まともなコンパイラセットなら、ライブラリ関数ごとのスタック消費
量まで書いてあります。
PCだとあんまり気にしないですけどね。。。とれるスタックの
量が桁違いですし。。。
組み込みだと4Kバイトとか8Kバイトがなんてのがよくあります。。。。
タスク1個じゃなくてシステム全体のスタックが128バイトです(;_;)
>>466 よくあることです。
で、ワーストケースの見積もり間違えで、悲しいことになる…
汎用機(日立VOS3/FS)のアセンブラを勉強したいのですが、アマゾンでも本がみつかりません。 IBMのsystem/370のアセンブラの入門書が見つかったので、とりあえず同じ汎用機だから似てるかなあと思って注文したのですが、 この本で勉強しても日立系でも応用利きますか?
470 :
デフォルトの名無しさん :03/04/12 22:14
便乗質問します。 スタックってやっぱり後方のアドレスから使うのですよね?
472 :
デフォルトの名無しさん :03/04/12 22:17
ただの金儲けさ。 そんな宗教やめておけ
>>469 今時どう言う理由で汎用機のアセンブラを勉強したいんだ ?
>>470 汎用のCPUの殆どが ハードウエアスタックを アドレスの大きい方から小さい方へむかって消費します
でも、特殊なCPU(1チップ系)はそうとは限りません。
>>469 使えるよ。
>>473 バグが出て読まなきゃいけなくなったに1000クロック。
>>474 俺のいじった数十種のチップには残念ながら無かった。例を挙げてみて。
>>475 例えばPIC なんかは PUSH でアップするのかダウンするのかマニュアルに書いていない。
まあ専用スタックなんで、そんな情報は不要なんだけどね。
今使ってるチップはスタックは2レベルしかない。 だから、スタック選択はカウンタではなく
フラグを反転するだけ。
>>476 ??私は469でしか書き込んでないですよ。
仕事でアセンブラを直接使うわけではないです。
主体はコボルなのですが、アセンブラで書かれたソースもあるので、少しは知りたいと思ったのが本を欲しいと思った理由です。
マニュアルって一般人でも買えるんですか?
>>478 > マニュアルって一般人でも買えるんですか?
そりゃ買えるけど、多分ソフトを一緒に買わないとダメだと思う。
汎用機のソフトって普通の個人じゃ買える値段じゃないと思う。(最近は知らんけど。)
仕事で汎用機使ってるなら、その管理者の人に言ってマニュアル買ってもらえば良いと思う。
アセンブラの勉強したいのでと言えば、普通の上司なら \300 ぐらいの経費は認めてくれるでしょ。
480 :
デフォルトの名無しさん :03/04/15 22:36
6502関係の資料(書籍など)を探しています。 学生の頃(4年前)にゲーム喫茶のマスターにプログラムを組んでくれと 頼まれて本を借りてそのままどこかになくしたんですが、 最近になって返してくれと言われて困っています。 なんでもいいので何かあれば教えて下さい。
(^^)
484 :
デフォルトの名無しさん :03/04/18 11:59
CODESEGMENT ASSUMECS:CODE,DS:CODE ; ORG5CH FCBDB12 DUP(?) DB25 DUP(?) BUFFERDB128 DUP(?) ; ORG100H ENTRY: ;保守上げ
>>481 thxです。6502日本語のサイトってないんですかね?
>>485 むしろ65816のサイトを巡った方が良いサイトが見つかるかも。
日本語のページはスーファミばかりの関係であまりいい所は
ないみたい。
488 :
デフォルトの名無しさん :03/04/19 01:05
>>486 全然無知なんですが6502と65816は同じ系統と考えていいんですか?
今探してる情報としてはコード表(?)を探してます。
「6502 コード表」でグルってもイマイチなんですよね・・・
>>490 ゲーム喫茶のポーカーゲーム賭博機も 6502 でつ。
未だ現役で動いてるだろ?
ファミコンのおかげで、あちこちの企業とかエンジニアの手元に資料はあるんだけど その為に逆にWebにまで資料を上げてくれる奇特な人はいないんだろうね
>>489 6502はファミコン、65816はスーパーファミコンに採用されたCPUですね。
それでここがミソなのですが、65816は6502互換モードというのを持って
おり、それに切り替えると(エミュレーションモードという)、拡張された
6502として使用できるようになっており、従って65816のサイトには同時に
6502の解説も書いてあるのが普通です。
∧_∧ ( ^^ )< ぬるぽ(^^)
∧_∧ ( ^^ )< ぬるぽ(^^)
498 :
デフォルトの名無しさん :03/04/27 16:10
逆アセンブルソフト で、オススメのやつありますか?
15F2:0100 MOV AX , FFFF 15F2:0103 MOV DX , 0001 15F2:0106 MOV WORD PTR [0200] , 100 15F2:010C DIV WORD PTR [0200] 15F2:0110 -G =100 110 AX=01FF DX=00FF axの01がどうやって出たのかどなたか教えていただけませんか? 宜しくお願いします。
>>499 1FFFFh / 100h = 1FFh 余り 0FFh
DX:AX [0200h] AX DX
ok?
ありがとうございます。 分かりました。 分子にはdx(この場合は0001)も含まれるのですね。axだけで考えてた・・。 ありがとうエロイ人 (・∀・)ノ
>>501 誰がエロイ人じゃ!
まあ分かればよろしい。
さて、半角に寄ってから寝るか。
>>502 > さて、半角に寄ってから寝るか。
エロイ人やん !!
_ (⌒Y´ ̄ヽ ∧_/( ̄)) ∧_∧ γ´ `ヽ_`と.__ )( ・ ∩( 《 ( ・∀・) ゴロン )) ,、 , ) <、_,.ノ ヽ、.__,ノ l つ つ ((_/し∪V .ヽ.__ノ!__)) ゴロン ∧__∧ ∧_∧ ∧_∧ ( ) ( ;´Д`) (・∀・ ) エロイ人から逃げられると思うなよ。 ( つ (U_U )つ (つ と) .ヽ___ノj 503 (⌒Y⌒) ∧__∧ . / ̄ヽ ̄ (・ ) __ ( __ ) ( ゴロン と ヽ ( ̄))∧_∧ /´ `Y⌒) VUVJ_) (__ト、__丿 〉 》∩ _) ( .__つ´ ヽ、.__,ノ ヽ、__,.>
初歩的ですが質問です。 ターゲットはWindowsなんですが、 関数を書くときに 破壊していいレジスタ/いけないレジスタ というのはあるのでしょうか? 今まで全部破壊してはいけないと思ってたのですが VC++で書いた単純なCコードに汗リストを吐かせると ebp しか push してなかったので。
eax ecx edx キャリーなどの算術フラグ 以外は保存すべき FPU SSEレジスタはコンパイラ毎に扱いが違うが関数呼び出しで破壊されると仮定した方が良い気がする
>>507-508 即レスサンクス!
汎用的に呼び出したい(更にはDLLにするかもしれない)ので
心配だったんです。
MSDNまで教えていただいたので公の仕様が手に入って安心しました。
#でもこんな奥深くにあったら分からないって
FPU SSEがコンパイラ毎に違うというのがちょっと気がかりですが、
今回とりあえず使わないので良しとします。
#破壊「されてる」のはコールした関数のバグかも、
#とか思えるからまだしも、自分が破壊してもいいものかどうか...
>>509 心配なら保存しとけばいいと思うが...。
511 :
デフォルトの名無しさん :03/05/01 19:54
Windowsだろうと処理系(コンパイラ)依存だよ。 Win32APIではEBX,ESI,EDI、EBPが非破壊。 このくらい調べられないようじゃお先真っ暗だぞ。
>>511 > このくらい調べられないようじゃお先真っ暗だぞ。
はい...頑張ります。
>>513 処理系によって引数の渡し方が異なるから、
まずはCで簡単なテストプログラムを作って
コンパイラにアセンブリ・リストを吐かせてみたら?
>>514 えぇと、C側は
?hoge@@YAXXZ PROC NEAR
みたいにハッシュ化(?)されちゃうようなんです。
毎回リスト吐かせて調べて
extrn ?hoge@@YAXXZ
みたいに書かなきゃいけないのかな、と思いまして。
>>515 それCじゃなくてC++だよ
extern "C"とかで対処
>>516 なるほど!
ありがとうございました。
あぁ、「このくらい調べられないようじゃ」という声が、、、
(・∀・)ノマァ、キニスンナ
519 :
デフォルトの名無しさん :03/05/05 04:09
int kakezan(int a, int b) { asm("imul %2, %0" :"=r(a)" :"0(a)", "r(b)" ); return a; } と int kakezan(int a, int b) { asm("imul %2, %0" :"=r(a)" :"r(a)", "r(b)" ); return a; } って 実行結果は同じなんですが、内部的にはどう違うか教えて下さい。
あ、""が間違ってますね すいません。
asm("imul %2, %0" :"=&r"(a) :"r"(a),"r"(b)); だよね
そっか インラインアセンブラ使えばいいのか と独り言
入力オペランド部の "0"(a) と "r"(a) の違いを・・・ どっちつかってもいいんですか?
>>525 %1見てないならどっちでもいいんでは?
527 :
デフォルトの名無しさん :03/05/05 20:59
>>519 よく分かってないんだが、
上のは、
mov eax, a
mov ebx, b
imul eax, ebx
だけど、
下のは、
mov ecx, a
mov ebx, b
imul eax, ebx
で、imul結果が不定にならない?
>>527 のレジスタは、てきとーに書きました。
出力の"r"(a)と入力の"r"(a)が同一レジスタに
なる保証はないのかと・・・
だから、"0"(a)なんて書き方があるのかと・・・
>>528 (誤)出力の"r"(a)
(正)出力の"=r"(a)
530 :
デフォルトの名無しさん :03/05/07 13:42
age
531 :
デフォルトの名無しさん :03/05/07 22:41
windowsで動くMotorola 68000 アセンブラってないですか? DOSで動くやつでもいいんですが・・・
532 :
デフォルトの名無しさん :03/05/07 23:02
アセンブラでウィンドウとか表示できないんですけ? 前にアセンブラとAPI組み合わせていたのを見たのだが。 なんでこんなこと聞くのって? いや、ウィンドウ使える新しい言語作る人とかいるじゃん? HSPとかACTIVEBASICとか・・・。 このかたがたってアセンブラで言語作ってんだと思っているんだ。 んで、この人達がEXEファイルを出力できるからさぁ、どういう仕組みなんだって気になってな・・・。
勘違いもいいとこだね。
>>537 別にX68k買わなくても
run68.exe+has.x
で良いような
539 :
名無し@沢村 :03/05/08 23:26
おれが、windows用のアセンブル言語開発環境(RADツール付き)をつくってやろうか? どうよ?
540 :
デフォルトの名無しさん :03/05/08 23:27
541 :
デフォルトの名無しさん :03/05/08 23:31
bcc32(tasm32)を使ってます 変数の型を short や char ではなく int にすると、 足し算するところに、よく、lea という命令を 使うようになります。 short の場合だと movzx, add などが連続しているのに対して int の場合だと lea だけですませているようです。 質問1 add よりも lea のほうが効率がいいのですか? 質問2 lea は int 以外(short や char など)では使えないのですか? 質問3 やはり int の計算は、char や short よりも効率がいいのですか? 質問4 整数の型は(たとえもっと小さい型ですむ場合でも) int を第一に考えるのが最も自然なのですか? ところで、最近、計算の型をそろえるということは 効率(実行速度)への影響が実は大きいのでは…と 感じてきました。 なんだかコンパイラ(アセンブラ?)が裏でコソーリとやっている 型合わせ処理が、無視できないコストなのでは…大げさかな アホな感想ですいません
543 :
デフォルトの名無しさん :03/05/10 07:18
詳しい理由はIntelのマニュアルぐらい読んで勉強すれ。 486-Pentiumクラスの知識で答えてるんで最近のx86じゃ 違うかも知れない。 1 殆どの場合no. つーか単純加算でleaなんか生成するっけ? 掛け算ならわかるが(eax*5 == lea reg,[eax+eax*4],etc) 2 だいたいyes. 16bitのleaはレジスタ組み合わせが少ない 3 yes. 4 yes. 型変換が結構なコストになるのは周知の事実だろう
544 :
デフォルトの名無しさん :03/05/11 04:34
お前らアセンぶってんじゃねーよ(プ
>>543 ありがとうございました
あ〜自分の型への認識を少し改めよう…
546 :
デフォルトの名無しさん :03/05/13 00:07
MOV AL,90H MOV DX,00F3H の機械語を教えてくれ
>>548 「そんなに長くなるわけねーだろ」と言いたそうだな。
まじお願いします_| ̄|○ MOV AX, CS MOV DS, AX みたいのならわかるんだが(´・ω・`)
お礼ならするぞ ('A`*( * )
WindowsXPにもdebugコマンドがちゃんとあるわけだが。
>>552 MS-DOSでやってるんだがエラーでる∧||∧
>>552 XP で DEBUG 起動した事ある奴と、UFO 見た事ある奴、どっちが多いかな?
|A`)誰か教えてくれ MOV AL,の部分まではB0になるのは分かるんだ 90Hやら00F3Hってのがわからねぇぇぇぇぇぇぇええぇぇぇっぇぇぇぇぇえっぇ
>>546 debugでは数値は16進数入力だから、後ろのHはいらんぞ。
>>556 アリガd
そんなことに悩んでた漏れ萎え。
tu-kaこんなことやってる大学ってうちぐらいか?
お礼
コイヨ('A`*( * )
debug.comはあんまり役に立たないからナァ symdeb.exeなら、結構役に立つが。mapsym使ってシンボルファイル 作って、学生時代にTurboPASCALのコードのデバッグしてた。 TurboDebuggerだとでかすぎて読み込めないプログラムも、ちゃんと デバッグできたし。 そういえば、新電子立国で一太郎の話が出とったときは、デバッガが symdebだったナー
たしかMS-DOS2.0か3.0までは、masmやsymdebも標準添付だったんだよなー。 一応DOSだけ買えば、アセンブリ開発環境は揃ってしまうと(w
>>560 98すか?
2.11がmasm+link+debug
3.1がlink+symdeb
で、そのうち拡張セット(だったっけ?)に入るようになった。
と思うんだけど、さすがに昔過ぎて記憶があいまい。
AT互換機の割り込みについてお教えください。 とりあえずDOS上からとDOSエクステンダ上からどれくらいの割り込み までかけられるのかなぁとやってみたのですが、割り込みコントローラ と割り込みリターンの速度上CPUが1GHz以上でも200kHzあたりで頭 うちになるっぽいです。 1.AT互換機上でやるのがまちがい 2.DOSでやるのがまちがい 3.80x86でやるのがまちがい 4.実はやりかたがある のどれあたりなのか、もしご存知ならお教えください。なんかせっかく クロックの高いCPUがあるのにもったいないなぁとおもったので・・・
>>562 仮想86モードを使わない。
x86って応答そんなに早くないけど。そこまでひどくないと思う。
単に空の割り込みルーチン?
それともI/Oに何か読み書きしてる? I/Oの読み書きするだけで結構
時間がかかるんだけど。。
あと
>>563 で指摘されてるよーに、DOSでHIMEM.SYSだけ組み込んでやれば
ちっとは速くなるんじゃないかナ。
>563 >564 なにも組み込んでないPC-DOSだと、仮想86モードにはなってないんじゃない かと思ってたんですが、実は違うんでしょうか? ちょっとぐぐってみました。EMM86って仮想86にして仮想EMSを実現してたの ですね。知りませんでした。HIMEMだけにしたり、なにも無い状態にしたりして テストしてみます。 >564 最初は8ビットI/Oを1ヶ所だけ読み出していたのですが、200KHzくらいのテスト の時には特定1ワードのメモリをインクリメントするだけの割り込みルーチンに しました。I/OにはEOIを書込みしています。 メモリの読み書きが遅いとは思えないので、割り込みの突入、EOIの書込み、 retiのどれかが重いと思っていたのですが、まさかこれらでμS単位の時間が 消えるとも思えないので・・・ お二方に教えていただいたことでまた実験してみます。ありがとうございます。
>>565 何の割り込みを使ってるのか分からんが「割り込みの突入」に
激しく大きなペナルティーがあるはず。
まぁCHIPSETなんてなかった単独の割り込みコントローラーが
あった時代の話だが、、、(^^;
定期的に200KHz以上の周期が本当に欲しいのか
デザインしなおすほうがいいかも。
普通は割り込み側にFIFOバッファなどおいて
割り込み周期は落とすようにしてある。
>566 使用してたのはISAバスの割り込み腺です。 4ビットカウンタを適当なクロックでまわしておいて、その値を割り込み時に 読み出すようなテスト回路を作ってみてました。とりあえず定期的な割り込 みで50〜1MHz位で試してみて、どのくらいまで取りこぼさずにとれるのか なぁって。1GHzのCPUで1000clockもあるわけだから、まぁいけるんじゃない のかな?って思ったのです。 さすがにISAバスももうないので、パラレルポートで割り込み&データ溜め 込み&HDDに記録&ちょっぴりの制御 なんかができたら、いろいろ遊べる かなぁと思ったのです。せっかくGHzクラスのCPUがあるんだし。 >激しく大きなペナルティーがあるはず。 >まぁCHIPSETなんてなかった単独の割り込みコントローラーが >あった時代の話だが、、、(^^; 今はチップセットなんかがCPUの近くで全部面倒見てるんだから、割り込 み応答も高速になってると思っていいんでしょうか?DOSから8259相当と してたたくと遅くなるだけとかだということなんでしょうか? >定期的に200KHz以上の周期が本当に欲しいのか >デザインしなおすほうがいいかも。 >普通は割り込み側にFIFOバッファなどおいて >割り込み周期は落とすようにしてある。 そういうFIFOのついた安いPCIのボードとかPCMCIAのカード、もしご存知 でしたらお教えください。さがしてみても数万円しちゃうようで、ちょっと遊 んでみるには高価なので・・・ お教えいただいてありがとうございます&長文失礼しました
568 :
デフォルトの名無しさん :03/05/16 16:13
Pentiumで、mallocとかで確保したメモリ領域を、 マシンコードと見なしてcallしたいんですが、 インストラクションコードがわかりません。 最初、nearの 8E <フラットアドレス32bit> かと思ったんですが、これじゃなくて、どうやら FF ?? <フラットアドレス32bit> という形式にしないと駄目らしいんですが、 ??に何を入れたら良いんでしょうか?
569 :
デフォルトの名無しさん :03/05/16 16:15
ちなみに<フラットアドレス32bit> は、32bitの絶対値です。
>>567 ISAバスだと、 4MHzじゃなかったっけ?
それと、割り込みとかDMAって技術はクロック数10メガの世界迄で、今のCPU速度にとっては双方邪魔
>>568 mallocで確保した領域をcall出来たかな?
VirtualAlloc で PAGE_EXECUTE_READWRITE とかで確保してないとダメじゃないの? Windowsだよね?
>>571 問題ないです。
普通にmallocした領域にインストラクションコードを並べるだけでokです。
567じゃなくて568でした
あ、つまり
>>568 の質問は、ヒープ上のマシンコードから
別のヒープのマシンコードをcallで呼び出したいという事です。
そのときのアドレスの指定の仕方で悩んでます。
最初のヒープの実行には成功してます。
ちなみに先ほど B8 <フラットアドレス32bit> ;mov eax, addr FF D0 ; call eax というEAXレジスタ間接呼び出しには成功しました。 これを直接、 call <フラットアドレス32bit> とできればいいんですが・・・
>>568 アドレスをレジスタに入れて
call eax
みたいな形でコール。
>>575 なんでインテルのサイトからpdfを落として読まないの?
E8 cd CALL rel32 相対 near コール、次の命令とディスプレースメント相対。
FF /2 CALL r/m32 絶対間接 near コール、r/m32 でアドレスを指定。
9A cp CALL ptr16:32 絶対 far コール、オペランドでアドレスを指定。
FF /3 CALL m16:32 絶対間接 far コール、m16:32 でアドレスを指定。
という事で、絶対 near コールは無い
>>567 割り込みの制御は今も基本的には同じ。
>>570 8MHzじゃなかったっけ?
たまーに10MHzとか言うのもいたような気もするが。
割り込みだけなら、バスクロックの影響は無いと思う。
Bridge経由になる分PCIより遅くなるかな?
>>577 その表の見方がわからんのです。
/2とか/3とか。
3.1.1.1. オペコード欄 /digit - 0 から7 までの数字で、命令のModR/M バイトがr/m ( レジスタまたはメモリ) オ ペランドだけを使用することを示す。reg フィールドには、命令のオペコードを拡張する数 字が入っている。 具体的にはその前の2章を読め
>>580 その辺のマニュアルの説明読んでも、
いまいち実際の値がどうなるのかがわかりません。
値の設定の仕方が何処にも載ってないし・・。
ちなみに今はVC6でstub作ってcodファイルから抜き出したものを コピペしてる状況です。 しんどいです。
>>581 そこは Try & Error で乗り切るしかないだろ。
昔、NASMのソース読んだりしてみたんですが、 さっぱりでした。 そういえば/3とかのフラグ系以外にも、 SIBバイトというのが意味不明でした。
だから 2章を読めって言ってるだろ 表 2-2. ModR/Mバイトによる 32ビット・アドレス指定形式 の表の上から6つめに /digit (Opcode) REG = ってあるだろ?
>>577 VCソースのstubに
___asm {
call 12345678
}
とか書いて、codファイル出そうとしたんですが、
>error C2415: オペランドの型が無効です。
でエラーになりました。
やっぱ無理っぽいですね。
>>585 お手数かけます。
これから読んでみます。
だからnear絶対コールは出来ない。でも、near相対コールで十分だと思うが?
>>585 ちなみに、どのマニュアルのことでしょうか?
IA-32 インテル(R) アーキテクチャ・ソフトウェア・デべロッパーズ・マニュアル
の、上・中・下巻が手元にありますが、これでいいんでしょうか?
あ、中巻ですね。
>>585 まさしくそれっぽいです
やっと意味がわかりそうです。
ありがとうございました。
592 :
デフォルトの名無しさん :03/05/16 17:50
C++のクラスをアセンブラで作るにはどうやりますか? 作り方の書いてあるホームページあったら教えてください 直接ここで教えてもいいですよ ちなみにレスはしません
>>591 折角pdfで提供してくれてるんだから、検索を活用してね。
>>592 作り方の書いてあるホームページないので教えません
595 :
デフォルトの名無しさん :03/05/16 18:42
作り方知ってるならここに書いて教えてーーーー
知らないけどC++のクラスだと型保証名の管理がやっかいじゃないの? どうせならC++で書けばいいじゃない。
597 :
デフォルトの名無しさん :03/05/16 18:45
MMXやSSEの使い方を教えてください。
598 :
デフォルトの名無しさん :03/05/16 18:49
masm7.0でmmxやsseが使えるかということも 教えてください
599 :
デフォルトの名無しさん :03/05/16 19:55
フラグを気にしない場合、 lea eax, DWORD PTR [eax+1] と inc eax ってどっちが速いんですか?
ice box
>>599 たぶんどっちでも同じだろう。 命令コードが短い方がトータルではキャッシュが効いて有利だ。
ただし、命令配置がくるって、逆に遅くなるなんて事もある程度の差でしかない。
603 :
デフォルトの名無しさん :03/05/16 20:00
なるほど。 短い方にしといた方が条件ジャンプとかでも有利ですよね。 ありがとうございました。
604 :
デフォルトの名無しさん :03/05/16 21:20
INC EAXって直感できないようじゃ、アセンブラはあきらめろ
>>604 ハッカーキターーーーーーーーーーーーーー!!!!!
606 :
デフォルトの名無しさん :03/05/16 22:40
MMXやSSEの使い方を教えてください。
>>606 いやです。
/ / \、i, ,ノ ヽ ヽ
| (-=・=- -=・=- ) |
608 :
デフォルトの名無しさん :03/05/16 23:05
嫌ならスルーしてください
俺はSSE2の使い方が知りたい サポートしているアセンブラ教えれ
610 :
デフォルトの名無しさん :03/05/16 23:21
NASMってサポートつーか、使えるんじゃない?
611 :
デフォルトの名無しさん :03/05/16 23:21
あと、Digital Marsのやつとか
612 :
デフォルトの名無しさん :03/05/16 23:26
ハイパースレッディングの概要と実装方法を教えれ
613 :
デフォルトの名無しさん :03/05/16 23:26
Intelのコンパイラも当然ながら使えるだろ
614 :
デフォルトの名無しさん :03/05/16 23:33
>>606 いったいぜんたい何回言われればわかるのか。
マ ニ ュ ア ル 読 め
そのマニュアルとやらはどこにありますか?
616 :
デフォルトの名無しさん :03/05/16 23:37
おい!だれかこのオシエテクンを連れてってくれ!
618 :
デフォルトの名無しさん :03/05/16 23:41
いくら最適化をかけても早くならない。なんとかしてくれ。
intelのアセンブラに付いて詳しく知りたいです 誰かおしえてぴょん
>>578 ISAは8MHzですなぁ。
マジメに速いのを作りたいなら、PCIの拡張ボードを自作してしまう
ことをお奨めする。取りあえず趣味で作るだけなら、I/O固定の
PCIモドキボードでもいけますし。下のとことかね。
ttp://elm-chan.org/works/pci/report.html つーか、1GHzのCPUと言っても、内部だけだからねぇ。外部は
所詮100MHzとか133MHzで動いてるわけだし。まして、I/OはPCI
なら33MHzだ。
sseとmmxが使えるアセンブラはnasmだけということでいいですか?
masm 7.1でも使えるっぽい(VS2003付属)
624 :
デフォルトの名無しさん :03/05/17 02:28
取ってくんのめんどーだよー masm7.1単体配布してるとこ教えて!
masm6.15でも使えるはず。VCPPで検索しる!
D6パーソナルの無料版でも sse mmx は使える。
627 :
デフォルトの名無しさん :03/05/17 15:21
masm7.1だけならフリーウエアだから誰かうpしてくれませんか?
> masm7.1だけならフリーウエア はつみみです
アセンブラは無料配布可になった。
ソースキボン
海外とかだと、ちゃんとしたアセンブラの掲示板に visual stuio netから取り出したmasm7..0が普通に配られてるよ
PlatformSDKに普通に含まれてますが・・。
アプしない人は黙っててくれる?
vcpp.exeとかいうのがそうかな
たしかM$のftpから落とせた気がするが
binフォルダの中身のファイル全部くれ いらない奴は捨てるから大丈夫
639 :
デフォルトの名無しさん :03/05/17 21:59
つーか配布形態がEXE形式しかないのがイカン ご自慢のcab形式にしてホシイ
※※※注意※※※ うp報告以外不要
641 :
デフォルトの名無しさん :03/05/17 22:44
masmは、MSのDDKに入ってるよ。MSDNの鯖から落とせる。
>>642 Win98DDKに入ってるのは6.11。古いんだyp!
vcpp.exe(VS6SP4用)かvcpp5.exe(VS6SP5用)には6.15が入っとる。
645 :
デフォルトの名無しさん :03/05/18 02:34
xor eax, eax push eax と push 0 ってどっちが良いの?
見た目的にはどっちでもいいな
>>645 無駄にレジスタ使う理由も無いだろうと思うがな。
ついでにレジスタ初期化する必要があるなら別だが。
648 :
名無し@沢村 :03/05/18 16:12
おまいらよ、アセンブラは使うよりも作るほうが簡単だぞ!! というのはアセンブル言語とマシン語は1対1で対応したものだから、単純な変換だからよ。 コンパイラのように字句解析とかパーサをつくる必要もないよ。 といっても、 MOV AX 100 の場合、MOVに対応したネイティブコード、AXに対応したネイティブコード、100に対応したネイティブコードと続いて保存されるわけではなくて、一命令の全部のオペランドが加算されてひとつのネイティブコードになるから、ちょっとややこしいけどな。 まあ、ものすごく根気のいる作業だが、難度の高いことは何もないから、おまいらもつくってみろ?
>>648 2パスアセンブラは結構作るのが面倒だった。
650 :
デフォルトの名無しさん :03/05/18 16:42
L1: <test-part> test eax, eax je L2 <then-part> jmp L1 L2: こういう相互ジャンプのジャンプ先のオフセット計算は スマートにやるとどうやるの? <test-part>と<then-part>のサイズによって、 short/nearジャンプの切り替えがある。 je L2はjmp L1の長さが判ってないとだめだし、 jmp L1はje L2の長さが判ってないとだめ。 それと、沢村うるさい。
>>648 マクロとか、欲しくなって複雑になっていく罠
沢村が何か言うと、やる気無くなる。
>>650 全部shortと仮定して、だめなところを順次nearにしていくとか?(あてずっぽう
>>650 簡単にやるには、1パス目で飛び先が確定していないものについては near だと仮定してしまう。
で、2パス目で実は short でも大丈夫とわかったら short にしてあとに nop を詰める。
> それと、沢村うるさい。
毎回言われてることだが、「無視しろ」。
656 :
デフォルトの名無しさん :03/05/18 19:42
PlatformSDKの中のどれをインストールすればmasm7.1がはいってるのですか?
DDKにしか入ってない
658 :
名無し@沢村 :03/05/18 20:27
おれは古いバージョンだが、masmは持っているよ。 masmにはたくさんのファイルがついてくるが、その中のQEditorというのが開発環境だよ。 このQEditorでアセンブル言語を打ち込んでアセンブルやビルドをするんだよ。 またQEditorにはプログラミングが楽になるようにテンプレートもついているし、APIやスクリプトも使えるよ。 なかなか高機能のアセンブラといえるね。 またBintodbというファイルはバイナリエディタだよ。
659 :
名無し@沢村 :03/05/18 20:34
フリーの開発環境いっぱいあるし QEditorなんて使ってられないよ
だめもとで聞いてみますが、 いい加減なコードを読ませたら、最適化しつつアセンブルしてくれるようなアセンブラって無いですか? push ESIとpop ESIで囲っている領域で、ESIを使って無かったら自動でpush/popも取り除いてくれるとか 計算を一時的にスタックを使って行っても、勝手に未使用レジスタを割り当ててくれるとか。 …無いですよね。無いですね。
>>663 そこまでやられたら、アセンブラの意味がないような…
やるならプリプロセスかなぁ?探せばありそう。
昔のコンパイラで、コンパイラのアセンブラ出力を最適化するのなんてのがあったが 今では TIのDSPくらいしか見ないな
>662 まだあったのか・・・わざわざInternet Archiveで落としてた
vcpp.exeに入ってたml.exe(6.15.8803) 欲しい人いる?
各自でvcpp.exeを落としてきてml.exeを取り出せばいいだけの話じゃないのか? 別にインストールせずとも簡単に取り出せるわけだし。
669 :
名無し@沢村 :03/05/22 01:29
━―━―━―━―━―━―━―━―━[JR山崎駅(^^)]━―━―━―━―━―━―━―━―━―
ml7.1以外は普通にダウンロード出来るからいらねよー ライブラリーとか付いて無いし単体だけあってもいみねーしー
673 :
デフォルトの名無しさん :03/05/22 21:08
神キター
ヘッダをincファイルにするって事なんじゃない?
vcpp.exe /c /t:c:\tmp とかすればc:\tmpに解凍できるんだけどな。
pdfファイルをふつうのテキストファイルか、またはHTMLファイルに 変換してくれるツールはないですか?フリーで または、インテルのサイトのマニュアルをふつうのテキストファイルか またはHTMLファイルに変換して公開しているところはないですか?
680 :
デフォルトの名無しさん :03/05/23 07:41
>>673 それだけだとアセンブラだけですよね。
ライブラリ、リンカ、逆アセンブラ・・・・
実際にMASMにはこの他に何があるのでしょうか?
教えてください。
681 :
名無し@沢村 :03/05/23 09:47
>>678 ハゲ!!おまい、PDFをふつーのテキストにしたら図や写真が見れねーだろ!!
PDFはRTFかHTMLにしねーとダメよ。
アクロバットリーダーはコピー&ペーストができねーから不便ではあるよな。
コピー&ペーストでもっと簡潔に読みやすくしてファイルサイズを小さくできると便利だよな。
おまいはちゃんと考えてみろ?
金出してアクロバット買え!
印刷汁
印刷してOCRで取り込め
685 :
名無し@沢村 :03/05/23 16:25
>>682 ハゲ!!アクロバットはフリーでDLできるよ。
10MB近くあるけど落とせ。
またテキストに変換するにはアクロバットでPDFを開いて「全て選択」「コピー」をし、
ワードパッドか何かにペーストすればいいよ。ただしテキストだけ、図や写真は無理だけどな…。
またPDFはサイズがでかいものが多いから、メモ帳じゃ無理があるよ。
ワードパッドかWORDのほうがいいよ。
687 :
名無し@沢村 :03/05/23 16:36
688 :
デフォルトの名無しさん :03/05/23 16:40
>>687 それは、Acrobat Readerであって、Acrobatとは違う。
689 :
デフォルトの名無しさん :03/05/23 16:42
>>685 Acrobat Readerにはコピーするテキストの長さに制限がある。
690 :
名無し@沢村 :03/05/23 16:43
>>688 だぁぁぁぁぁぁぁぁぁぁぁぁぁぁぁあああああああああああ
あああああああああああああああああああああああああああ
あああああああああああああああああああああああああああ
あああああああああああああああーーーーーーーーーーーー
ーーーーーーーーーーーーーーーーーーーーーーーーーーー
ーーーーーーーーーーーーーーーーーーーーーーーーーーー
ーーーーーーーーーーーーーっ!!!きさまぁぁぁぁあああ
あああああああーーーーーーーーーーーーーーーーーーっ!
おまえら沢村と会話するとろくなことがないぞ
>>689 > Acrobat Readerにはコピーするテキストの長さに制限がある。
ふ〜〜〜ん、今 800ページ (6MB) ぐらいのやってみたけど、ちゃんとコピペできたよ。
どこまで必要なの ?
まさか、メモ帳に貼り付けて途中までしかコピーしてね−とか騒いでいる厨房じゃないよね ? (藁
win95系というオチでは?
沢村はとっととNGNameに入れとけ。
>>694 特撮板のシャイダースレ見るとき困る(爆)
そろそろ(爆もNGWordかしら(゜Д゜)
昔こういうのもあった(ぉ
698 :
デフォルトの名無しさん :03/05/27 19:46
CQ出版のintel486あたりのマニュアルには 1オペコードごとのクロック数が書いてあるんですが 今のインテルから落とせるマニュアルに(中巻)に はクロック数とか書いてないんですよね 686とかNetburstは 1オペコードあたりのクロックは状況によりけりってことでしょうか
そうですね
686以降は内部でマイクロコードに分割されて、アウトオブオーダー実行される。 順序どおりに実行されないし(結果は順序どおりに反映されるけど)、 レジスタリネーミングなんかもあいまって、内部で起こってることを予想するのすら困難。 ハッキリしてたのは586までかな。
>>701 どんなエラーがでるかくらい書け。
それから、そのページのプログラムはみんな.com用の様だが?
>>702 COMなんて時代遅れスよ。これからは.Net
704 :
デフォルトの名無しさん :03/05/28 00:22
アセンブラ初心者です。アセンブラとの関わりは情報2種をCASLで取った位です。 最近ブックオフで「はじめて読む8086」という本を偶然見つけて買いました。 MS−DOSのコマンドプロンプトで簡易的にアセンブラを体験できる事を初めて知りました。 とりあえずこの本をマスターしようと思います。
「基本情報」じゃなく「情報ニ種」時代の年寄りが今からそんなことやるのかいな。 普通に他の言語覚えれば?人生は短いよ。
2種を取ったのは学生時代の2000年秋です。 今はCOBOLERです。 古いプログラムにはアセンブラもあるので、それを少しでも分かればと思って。 704の本はもう今週中には読み終えるので、それからC言語の復習→Javaと勉強する予定です。 IBM汎用機のアセンブラの本も同時並行で読んでいくつもりです。
いまさら8086じゃしんどいと思うよ。 intとかの割りこみは勉強になるだろうけど。 これからやるなら386以降が楽しいと思う。
80386ですね?ではそれも本屋で探してみます。
>>708 本買う必要ないよ。入門書は1冊軽く読む程度でok。
図書館行った方が良質な本が見つかる可能性が高い。
CPUがIntelであれば、マニュアルはWebサイトから落とせる。
あとはgoogleでasmやらeaxやらで検索すれば色々サイトが見つかる。
例えば
ttp://tt.sakura.ne.jp/~suzu/asm/index.html とか。
上のサイトでも書いてある様に、32bitのアセンブラはCと連携する
事が多いから、Cも多少かじっとくと学習効率がいいよ。
(アセンブラだけでももちろんいいけど)
intelのマニュアル
http://www.intel.com/jp/developer/design/pentiumiii/manuals/ ここの
・IA-32 インテル(R) アーキテクチャ・ソフトウェア・デべロッパーズ・マニュアル、上巻:基本アーキテクチャ (日本語 PDF ファイル: 4,183KB)
・IA-32 インテル(R) アーキテクチャ・ソフトウェア・デべロッパーズ・マニュアル、中巻:命令セット・リファレンス (日本語 PDF ファイル: 9,139KB)
・IA-32 インテル(R) アーキテクチャ・ソフトウェア・デベロッパーズ・マニュアル、下巻:システム・プログラミング・ガイド (日本語 PDF ファイル: 7,838KB)
この3つの中身は知っておいた方がいいよ。
(命令とかを全部覚える必要は全くない)
AMD英語で(´・ω・`)…。
713 :
名無し@沢村 :03/05/28 06:37
おまいらよ、おれはいま量子指向言語の構想を練っているよ。 ふつーの言語では演算によって結果を求めるが、量子指向言語ではすべての結果は重ねあわせの状態ですでに存在しているから、その中から求める結果を選ぶだけよ。 求める結果は重ねあわせの係数で決まるのよ。 このあたりがいままでの言語と大きく文法が異なるところだな。 つまり画期的よ!!! おまいらよ、これからの言語といったら量子指向言語しかないぞ!!量子でない言語なんてザコだぞ!!
>>713 いいから病院いけ
そんなんだとこの先つらいぞ
>>714 なんでそんな簡単に釣られる...。
いいかげん放置しとけよ。
∧_∧ ピュ.ー ( ^^ ) <これからも僕を応援して下さいね(^^)。 =〔~∪ ̄ ̄〕 = ◎――◎ 山崎渉
MASM32の日本語解説サイトきぼん
>>713 なぁ、ヌヒよ。それは、ニューロコンピューた言うんとちゃうのか?
沢村と会話するな! これ、俺からのお願いだ。
>>709 ,710,711
おおお、これはこれは親切にありがとうございます。
参考にさせていただきます。
アセンブラでメモりに常駐して、キーボド操作で ショートカットみたいなことをしたいんですけど、 この場合 【1文字入力】 AH = 01,06,07,08のいずれか DL = FFh(AH=06のときのみ) INT 21h これ↑は使えるのですか?
DOSの話? DOSの場合、そのINT21かキーボードbiosをフックするんじゃなかったかな
>>722 アセンブラなんだからCPUとOS書いた方がいいよ
条件分岐はパイプラインを乱すので、できるだけ避けるべき とよく聞きますが、では、条件分岐とは具体的に何の命令を 指しているのでしょうか? cmp, test, jmp, jz, jge, cmov, pcmpgt, ...?
>>725 例に出ているのだと
jz,jge
こういうことは、アセンブラで一通り書ける様になってから考慮すれ、
>>723 お手数をかけますが、サンプルコードを書いてくれまへんか?
それか、参考になるwebページだけでもイイですから…
>>726 ここで、divの使い方を聞いて、その後にMMXのソースを書いていた者です
jz,jgeは乱すけど、その他は乱さないのですね。
cmp,testが乱さないのは、なんだか驚きました、が、
動作の意味が非破壊(とかいうヤツ)だから納得しました。
ところで、jmpは乱すのですか?無条件なのに?
ようするに、書いてある順番に実行されるかされないか、ということ?
間接ジャンプは乱すと思った
実行の流れを決定し、かつ実行時にならないと流れがわからない命令が乱すもの。 条件分岐は分岐する/しないが実行時でないと確定しない。 また、分岐先アドレスが即値ではなくレジスタが含まれる場合も同様。 「分岐予測」を参考のこと。
あーん?条件分岐がわからない?? 日 本 語 か ら や り な お し
予測分岐に失敗したときと add eax, ebx sub eax, ecx みたいなレジスタのストールにぶち当たった (スケジューラでも並び替えできなかった) 場合の遅延時間はやっぱり同じなの?
>>732 試してないので想像だがレジスタリネーミング失敗のペナルティの方が
断然小さいと思われ。
条件分岐の予測失敗がおきると、並行して実行していた後の命令を
途中ですべて捨てて最初からやり直しになる。
パイプラインあたりを勉強しる!
735 :
デフォルトの名無しさん :03/05/30 15:58
すいませんアセンブラの初歩の質問させてください push ebp ・・・・ア この次の行で mov ebp,esp ・・・・イ こうする事になんの意味があるんでしょうか? 「ア」でebpの値(仮にA)がスタックespに保存され、 「イ」ではスタックの最新の値(つまり、A)がebpに上書きされるだけで ebpはA→Aで何も変化しませんよね?2行目はいらないんじゃ・・・
ebp はスタックフレームとして使います。 ebpを基準にローカル変数や引数をアクセスするわけです。 別の関数を呼ぶと、その関数の中で新しくスタックフレームを作り 関数終了時に呼び出し前の状態に戻さなければいけません。 そこで、push ebp で ebpを保存しておいて mov ebp,esp で現在のスタックポインタを ebpに持ってくるわけです 関数終了時は逆に esp<-esp にして pop ebp する事になります。
>>735 > 「イ」ではスタックの最新の値(つまり、A)がebpに上書きされるだけで
ここが間違っとる。
espの値がebpに入るんだよ。スタック上の値じゃない。
739 :
デフォルトの名無しさん :03/05/30 18:42
>>735 mov ebp,esp と mov ebp,[esp]の違いが分かるか?
>>730 をはじめとして、説明がわかりやすかったです。
ありがとうございました。
わかりますた。ありがとうございます
アセンブラ最高!
743 :
デフォルトの名無しさん :03/06/01 14:23
質問お願いします。とあるソフトの、あるアドレスが持つデータを 監視したいと思っています。ところが調べてみたところ、 このデータのアドレスが、毎回変わってしまうことに気づきました。 そこでそのアドレスを保持している箇所を調べてみました。 そこが固定な数値なら良かったのですが、実際は下記の通りで詰まってしまいました。 MOV DWORD PTR DS:[ESI+32],1 はたしてこのESIの値を特定することは、がんばれば可能なのでしょうか? 当方「はじめて読む8086」を読んだ程度しか無いので、 どんな些細なアドバイスでも頂ければ嬉しいです。
自分でいうのもなんですが、これだけじゃあまりにも情報不足ですね・・・
デバッガでその命令にブレークをかけて、周辺コードを脳内バックトレーサに入力。
>>745 レスありがとうございます。凄い助かります。
やはり地道に追うのが一番なんですね。固定値でるまでやればいいのかな・・・。
貧弱な脳内ですが、ブレークポイント置きまくりで頑張ってみます。
しっかし難解ですねぇ(´Д⊂
そのコードの、その部分のソースを持ってはいないの?
> 毎回変わってしまう これが何の毎回かわからないけど、 その命令にブレークかけて、その時点のレジスタの値でデータのアドレスは 算出できるから、変わってしまうまではそのアドレスで監視できないの?
皆さん、おつき合いありがとうございます。
>>747 はい、残念ながら無いみたいなのです…(一応うちの専用ツールみたいですが)
>>748 言葉足らずですいません。毎回=対象ツールを起動する毎にです。
748さんの仰る通りにできる技術が、私にあれば良いのですが(´Д⊂
実際はReadProcessMemoryで、そのツールの指定アドレスを監視するのが精一杯でして・・・。
(Win環境で、監視ツール自体はC&WinAPIで書いてます)
しかしレジスタの値を、読めれば本当に一発ですね。
読むタイミングは問題無さそうなので、レジスタの読み方を勉強してみます。感謝です。
> 読むタイミングは問題無さそうなので これは失言でした・・・そんな単純じゃないですね。
>>749 Windowsなのか
だったらHookを使ってDLLを読ませてコード自体にパッチを当てるのが楽
>>751 馴染みのある言葉が、出てきてホッとしたのも束の間、
理解できる頭がなかったりで・・・。DLLの置き換えや
グローバルフックの事では無いですよね。
ちょっと検索したくらいじゃ分からなくて(レジスタの方も)・・・、
折角良いアドバイス頂いたのに、生かせなくて情けないやら不甲斐ないやら。
もう少し修行して出直してきます。方向示唆、ありがとうございました。
(それでもアセンブラ、面白いですねぇ)
最近、気がついたのですが… 以下のアセンブラコードを出力させると #include <windows.h> extern int f(int x); void g() { f(0); GetDC(0); } f()については、push/popが組になっているのですが GetDC()についてはpushだけでpopがなく、 組になっていないのですが…なぜでしょうか? なんか怖いのですが
APIはpascalスタイルだからですよ。
>>754 ごめんなさい、これだけではよくわかりません…
もう少し詳しくお願いします
>>755 MSDN読めってことですよ
cdecl
stdcall
で検索
754じゃないけど、スタックを元に戻すのが「呼び側の担当」か 「呼ばれ側の担当」かっていうルールが、言語毎にあるんでしょ?
規定している言語もあるし、規定していない言語もある
> Win32APIは、全部が__stdcallなのでしょうか? 注意書きがない場合はすべてそうです。
なるほど、わかりました。 解決できて、すっきりしました。 どうもありがとう
今68000アセンブラとCVME-680マイコンを使って モニターの機能を作りました(単に打った文字を表示するだけw) そんでその機能をつかって簡単なタイピングを作ろうと思うのですが バックスペース、エンター、カーソールキーを押すことでいろいろな 動作を行いたいのですがマイコンの方でどのようにこれらのキーを 押したことを判定すればいいのでしょうか?たとえばAという文字を 打つならマイコンの方でAにあたるアスキーコードで判定できるわけですが これらのキーにもアスキーコードなりなにか割り当てられているのでしょうか?
>>762 機種依存なのでなんとも言えない。
エコーバックするプログラムが組めるんなら、
文字コードを表示するプログラムでも組んで確かめてみたら?
>>763 そうっすかー
地道に調べてみます・・・
>>751 ちとオレも詳細キボンしていいかな
アプリやゲーム起動するごとに、それを感知してコードを書きかえるってこと?
違うか…
>>765 いやその通り
MOV DWORD PTR DS:[ESI+32],1
と前後の命令をサーチしてCALL命令なりに書きかえれば
ESIが得られるのではないかという話
>>766 のるほど、なるほど、いや凄いやり方があるもんだな
一つ賢くなったよ、レスサンクスです
MIPSのR系のCPUのLinuxでアセンブラなんですが、cからソースを 吐かせると擬似命令で.cploadや.cprestoreが使用されてるんです。 デバッガで見ると擬似命令のところにレジスタに値を入れてるような コードが・・・このcpload等の擬似命令がなんのものかご存知ないで しょうか? PIC(position-independent code)には必要とかなってて、どうも外部 ライブラリを呼び出す時に必要らしい?ところまではわかったのです が、正確にはわからないでいます。ライブラリを呼び出さないサブルー チン自身でも上記擬似命令で使用していないレジスタ操作をして、上 位にリターンして他の関数にはいったらまた破壊され・・・となんの役に も立ってないように見えるんです。実際に削ってコードかいても一応 動作したりするのでより混乱してます。
『MIPSpro Assembly Language Programmer’s Guide』に書いてない? Webからpdfが落とせるはず。
gpレジスタ相対で変数をアクセスするためのコードだったと思う。 gpレジスタ使うシステム(libraryが使ってるとか)じゃなければ必要ないので、 gcc -mno-abicalls すればよろし。出力されないよ。
>769 早速落として読んでみます。 >770 たしかにデバッガでみてみるとgpレジスタを更新してたような気がします。 正確にはマニュアルを読んで確認となるんでしょうが、教えていただいてgpレ ジスタ相対のためのものって言うのがわかってかなりすっきりしました。 お二方ありがとうございました。
計算結果として例えば17が返って来て それを表示するにはどうすればいいっすか? アスキーコードしか使えない場合のみでお願いします 1を表示するには数値0x31、7を表示するには数値0x37 を入力するようにすればいいのですが17をどうやって その二つに分ければいいのやらわからないっす
アセンブラに関係ないような・・・ 10の桁・・・10で割った数値に0x30足す 1の桁・・・10で割ったあまりに0x30足す
確かに関係ありませんね すみませんです・・・ 68kアセンブラで割り算ができないのですが その場合は地道に引き算しかないですか?
>774 >68kアセンブラで割り算ができないのですが 意味が分からない。 本当にアセンブラが割り算命令を解釈できないなら 命令コードを直接数値で書いてしまえばいい。
Z80って、まだ現役ですか?
>>775 できました!どうもありがとうございました
確かにアセンブラでやる必要ナッシングですね(w
まったくアセンブラに関係ない質問すいませんでした
>>774 これこれ、嘘はいけません。
divs/divu命令ありますがな。
68kのアセンブラなら、ぐぐれば過去の遺産が大量に引っかかるはず。
divって、フラグに影響がでる(変更される)けれど、 その値は不定なのでしょうか? なんだか妙な感じにみえるのですが
あ、直前で68kの話題がでてるけど… 私のは関係無くて、Intel系の話です
>781 8086とか最初のころに未定義としてしまったから、以降もわざわざ 定義せずにいるほうがプロセッサの実装が楽になるかもとかあった のではないでしょうか? 最近だとちゃんと命令順に実行されないので更に複雑怪奇なフラグ 反応になってるか、NOPのように無反応とかかも・・・
>>778 あ、検索にひっかかりましたね・・・
日本語のサイトばっか探してたんでダメだったみたいです(w
これからはそれをつかってやります(やっぱ見にくいし)
引き続き駄レスすみませんでした
>>782 つまり、不定ということですか?
歴史的な理由があったのですか…しらんかった
フラグを使えないのは不便だな〜
>>776 本家ザイログ製のZ80はだいぶ前に製造中止だが、
互換チップは何種類か生産されていて現役。
Z80プログラムの需要もある。
アセンブラコードを出力すると、関数の先頭で、 以下のようなコードをよくみます push ebp mov ebp,esp この時点でebpとespが同じ値を持ってますが… アセンブラがわざわざmovしているのだから、 ebpにespの値をセットしておくことは重要だ (プログラマはebpレジスタを破壊してはいけない) と思いました。 それでは、もともとその値を保持していたespレジスタは、 もはや破壊してよい (プログラマはespレジスタを自由に使ってよい) といことなのでしょうか? つまり、関数の中で 自由に使ってよい...eax,ebx,ecx,edx,esi,edi,esp 使えない...ebp ということでしょうか?
>>786 > それでは、もともとその値を保持していたespレジスタは、
> もはや破壊してよい
まあこれはいいとして (よくないけど) ...
> 自由に使ってよい...eax,ebx,ecx,edx,esi,edi,esp
なんでこんな結論に至るんだ ?
eax, ... edi は保存されて無いだろ。
>>787 >なんでこんな結論に至るんだ ?
>eax, ... edi は保存されて無いだろ。
保存しておけば、自由に使っていいのですね?
これらのレジスタを使ったら、保存するコードを
プログラマが書かなくても、アセンブラが自動的に
追加してくれているようでした(ありがたいことだ)
ところで、
>> それでは、もともとその値を保持していたespレジスタは、
>> もはや破壊してよい
>まあこれはいいとして (よくないけど) ...
これは、どういうことでしょうか?
いい?わるい?
どっちでしょうか?
espもebpも、そのまま触れないでおくのでしょうか
あまりにもくだらなすぎるしつもんのためまじめにこたえる きがおきまへん。
マジレスするならコンパイラ依存
>>790 > マジレスするならコンパイラ依存
わかりました。
スレを汚して失礼しました。
あ〜
しょうもない質問で非常に申し訳無いんですけど 特定の値に序所に近づけていくためのコードを究極にまで高速化したいんですけど 良い方法ないですかね?、3ヶ月ほど悩んでるんで。 無かったら放置でお願いします、 まぁ微妙にスレ違いですけどほかに適所がみつからなかったんで、 C言語か86アセンブラでお願いします int value = xxx; int value_target = 5120; void func(){ if(value < value_target)value++; if(value_target < value)value--; }
そんなに何度も呼ばれるのか?
サウンドプログラミングでつ。 秒間41000かいよばれます
間違え、44100
こんなもんCでもアセンブラでもかわらん。意味ない
Pen3ぐらいあれば44100回/secぐらい余裕だと思うけど
これらを変数10*16個に対して行うんで、 まぁ結局条件分岐つかうしかないんですかね…
あえて書くなら(value>0 を仮定) MOV EAX,[value] MOV ECX,[value_target] CMP EAX,ECX ADC EAX,0 CMP ECX,EAX SBB EAX,0 value<0もあるなら普通に汁
>>798 ADC r/m,0
SBC r/m,0
サウンドだから負もあるだろうよ
かぶった しかもSBCはZ80だった
>>799 800
なるほど、サンクス。
しかしこれ、変化量1以外だと無理っす…
ようするにあきらめて条件分岐しろってことですかね
SBB EAX,EAX AND EAX,任意 ADD 何か,EAX とか クリッピングがレアケースなら 分岐予測に任せた方が速い場合もあるよ
value_target>0も仮定しなきゃいかんのか
>>803 MOV EAX,[value]
MOV ECX,[value_target]
CMP EAX,ECX
SBB EDX,EDX
AND EDX,-変化量
ADD EAX,EDX
後半は自分で考えて
おっと今度は俺がかぶった・・・まあ定番テクだな
ちったは勉強汁!
>>803
勉強不足を実感しますた、もっと勉強します。 どうもありがとうござました。
っていうか1ヶ月前、CMPでどうやってフルビットたてたり消したりするか ずっと悩んでたんだけどまさかSBBを使うとは… こういうのってアセンブラやってる人にとっては常識っぽいけど どうやって勉強してるんですか? まぁそれを調べるのからして 自分でしなきゃダメって言われたらもうそのとおりなんですけど。
>>808 99%の努力(人のソースを読む、コンパイラの出力を読む、gccのソースを読む)、
そして1%のひらめき。
嫌いな言葉:努力
>>788 > これは、どういうことでしょうか?
> いい?わるい?
いいか悪いか自分で判断できないなら使うなよ。
AXレジスタの値によってキャリーフラグを設定したいのですが AX == 0 -> CF = 0 AX != 0 -> CF = 1 とするにはどうすればいいのでしょうか?
>>812 CMP AX,1
無理してアセンブラ使わないほうが良いんじゃない?
>>812 これって AX == 2 のときでもキャリーフラグが立つのでしょうか?
0のときに立つからCMCで反転して
>>815 あぁ、なるほど!
どうもありがとうございました
AXが壊れていいなら -1 を加算
void main() { register short int a = 100; register short int b = -200; a = b / 2; if ( a > b ) a = 1; else a = 0; } 上のCソースに対してgcc -Sを使って吐かせると、 a = b / 2の部分が以下のように出力されました。 movl $-200, %edx movl %edx, %eax sarw $15, %ax shrw $15, %ax leal (%eax,%edx), %eax sarw %ax 私は、この部分は、算術右シフト命令のsarだけで終わると 予想していたのですが・・・。 なぜ上のようになるのでしょうか? どなたか教えてください。
負数の割り算はsarじゃすまないヨー
やっと分かりました!つまり、 符号を表す最上位ビットを取り出して、 それを加算することによって0の方向に丸められるようにする これで、あってますか? これで一応解決しましたが、気になる所が・・・ 先ほどのアセンブラの sarw $15, %ax shrw $15, %ax この部分は、なぜ算術右シフトをした後に、シフトしているのでしょうか? シフトだけで良いような気がするのですが・・・。
MSBをLSBに持ってくるだけだから、論理シフトだけでいいという事だね
>>821 そういうことです。論理が抜けてましたね。
算術右シフトをしないと何か困ることでもあるのでしょうか?
確かにsarwは不要だと思うよ。 たぶんさ、short にしてるでしょ? だからそこまで最適化されてないんじゃないの? コンパイラにしては頑張ってるコードだと思うよ。 自分なら符号付1/2は 左シフトして Add With Carry して算術シフトかな
>>823 > 確かにsarwは不要だと思うよ。
> たぶんさ、short にしてるでしょ? だからそこまで最適化されてないんじゃないの?
> コンパイラにしては頑張ってるコードだと思うよ。
なるほど。
> 自分なら符号付1/2は 左シフトして Add With Carry して算術シフトかな
おぉ、そういう方法もありますね。
16ビットシフトして最上位ビットがキャリーフラグに入るのを利用する、ということですね。
いろいろと勉強になりました。最後にひとつ。
sarw %axはsarw $1, %axと同等ですよね?
シフト回数を省略したら普通1だよね。 他に sar 15bit して 元から引くという方法もあるね
>>825 な、なんと。-1を引いて、+1の加算ってことですか。
高級言語なら1行ですけど、その1行の部分に
様々な発想が生まれますね。
アセンブラはおもしろいですね。
-O3 くらいにしたらもっとマトモなコード出さねーか?
>>817 > AXが壊れていいなら -1 を加算
これもスゴイ!
どうもありがとうございます
>アセンブラコードを出力すると、関数の先頭で、 >以下のようなコードをよくみます >push ebp >mov ebp,esp 786でこんな質問をしました。 なんとなく意味がわかってきた気がするのですが、 以下であっていますか? ebpはこの関数でこれから使うスタックの先頭を指し、 espはスタックの最後を指す。 スタックの最後とは、この関数で使うスタックの最後でもあるし、 プログラム全体で使っているスタックの最後でもある。 C++のコンテナクラスのbegin(),end()に似ている。
>>829 続き
文字列でたとえると、
| ↓ebp ↓esp
|■■■■□□□□□
|
←メモリの後方 メモリの前方→
ebpの値を保存し、ebpにespの値をいれる事で
部分文字列の先頭をセットする。
この先頭の位置を基準にして文字を追加していく。
追加するたびに最後の位置を表すespが進む。
関数の最初でebpとespが同じ値になっているのは
まだなにも追加していないからだ。
push eax と書いてある場合、espはここに表示されてないが
espの値は変更される。
ebp,espともに大事な値を管理しているので
破壊してはならない。
push ebp mov ebp,esp とするのは、そのようにした方が関数の引数やローカル変数が扱いやすいから。 引数やローカル変数はスタック上に置かれるが、espを基準にアクセスすると push/popするたびに基準の位置が変わってしまって面倒。そこで、関数に 入った時点のespの値をebpに入れて、以降はebpを基準にアクセスする。 最近はめったに使われないが、これのための命令としてenter, leaveというものもある。
832 :
デフォルトの名無しさん :03/06/12 22:00
コンパイラによっては、全てESPでスタックを見る最適化を する。この場合、EBPはレジスタ変数として使える。 EBPを使う場合は命令長が短くなるのがメリット、なんだけど、 Pentium以降のコードキャッシュが大きいCPUでは殆ど意味が ないんじゃないかと思う。
>>829 gcc だと omit-frame-pointer あたりで抑制可能。
それやっておくと、ebp+4 が常にreturn address となって色々ハッピーなのだよ。
( ゚∀゚)
(A) mov edi, offset global_x offsetってアセンブラがアセンブル時に 解決してくれるのでしょうか? (global_xは大域変数です) (A)は「レジスタに即値を転送」ですか? (B) mov edi, offset global_x+4 この例もそうですか?足し算をしてますが…
実際にアセンブルすりゃすぐわかるでしょーが どいつもこいつも質問する奴は手を動かさないカスばかり
そういう低級労働者特有の発想はやめてくれない?
あっそ
寂れてるな・・・
大量データのコピーに、MMXを使うとrep movsdより遅くなるみたいなんです。 自前でループする時のコストが高いのかな。
>>841 ありがとう。
アラインメントは16バイト、アンロールは1回行なっています。
もう少しディープにやってみまつ。
>>840 とりあえず、ソースさらせ
話はそれからだ
>>843 PC壊れた(涙
どうもグラフィックカードが曲がった感じです。
ケーブル抜かずに引っ張り出したのがいけなかったみたい。
修理後、ベンチやり直して今回の謎(漏れだけか?)を解明したいと思います。
という訳で次の方どうぞ。
845 :
デフォルトの名無しさん :03/06/30 14:21
ヴぁ
846 :
デフォルトの名無しさん :03/07/05 12:06
Linux上でx86系アセンブラの勉強を始めたいのですが、 何かいい書籍orサイトありますか? アセンブリ言語はほとんど未経験なので、本当に初心者向けのものがいいです。
$gcc −S が一番じゃね?
848 :
デフォルトの名無しさん :03/07/05 12:13
答えられる人だけでいいです...
THX!!!
851 :
デフォルトの名無しさん :03/07/06 03:15
Linuxのフレームバッファを使ったメガデモって無いの?
浮動小数点命令を使いたいのですが、汎用レジスタから浮動小数点レジスタへ 値を直接転送することはできないのでしょうか? 汎用レジスタで計算したあと、いちいちメモリに書きこんで、 それをロードする形式をとっているのですが、もどかしく感じます。 (特に、関数を呼び出して、その返り値を使うとき)
自己解決しました。 movntq[MMX2]なんてあったんですね。 また質問お願いします。 PIIIからP4に変えたのですが、 P4で正確に実行クロック数を測定するのは無理ですか? いろいろやってみたのですがダメでした。 HTは無効にしてあります。 宜しくお願いします。 {PIIIの時のソース} xor eax,eax cpuid rdtsc mov start,eax mov start+4,edx xor eax,eax cpuid [テストしたいコード] nop nop xor eax,eax cpuid rdtsc mov end,eax mov end+4,edx テストしたいコードがある時と無い時の差を実クロックとしています。
>>853 Pentium2です
それから、実は
movd mm0, eax
って、内部では
レジスタ→メモリ→レジスタ
という動作をしているのだろうか…?
なんども繰り返したときの平均値しかわからんねえ。
その… ・汎用レジスタと浮動小数点レジスタは直接やりとりできない(?) ・MMXレジスタと浮動小数点レジスタは同じもの と思ったからです。 そんなことはなく、汎用レジスタとMMXレジスタは 直接やりとりできるのか
妄想はダメyo
のもるあ
あるもの
>・MMXレジスタと浮動小数点レジスタは同じもの ソフトウェアから見たら同じに見えるだけで、内部的には別物じゃなかったか。
>>863 命令上、別のレジスタに見えるけど、内部は同じもの
じゃないの?
IA-32の仕様では同じもののはずだけど PenIIから内部的に別レジスタになったんじゃなかったかな 仕様との辻褄あわせをどうやってるかは知らない (ペナルティが発生する?)
866 :
デフォルトの名無しさん :03/07/12 15:02
byte p[4]; とした時、 movd mm0, p pxor mm1, mm1 punpcklbw mm0, mm1 movq mm2, mm0 punpcklwd mm0, mm1 cvtpi2ps xmm0, mm0 punpckhwd mm2, mm1 cvtpi2ps xmm1, mm2 movlhps xmm0, xmm1 で、p を xmm0 に入れることができたのですが、もうちょっと簡単な(効率が良い)やり方があったら教えてください。 同様に cvtps2pi mm0, xmm0 packssdw mm0, mm1 //packusdw が何故か無い・・・ shufps xmm1, xmm1, 78 cvtps2pi mm2, xmm0 packssdw mm2, mm1 //packusdw が何故か無い・・・ packuswb mm0, mm2 movd p, mm0 で、xmm0 を p に戻すことができたのですが、もうちょっと簡単な(効率が良い)やり方があったら教えてください。
拡張命令のニモニックってなんか滅茶苦茶だよな
868 :
デフォルトの名無しさん :03/07/12 18:24
上の方 L2: 下のほう movl$1,%eax addl%eax,%ebx movl%ebx,-16(%ebp) movl$100000,%eax cmpl%eax,%ebx ←ここについて突っ込み無用(w movl-16(%ebp),%eax movl-8(%ebp),%ebx jlL2: な感じしたんですけどjlでL2のアドレス(004010CB)に飛ばず おかしなアドレス(003FDECB)に飛んでSegmentation faultが 発生するんです。 何かご存知の方がいたらご教授ください。 お願いします。
>868 標準語でおながいします。
870 :
デフォルトの名無しさん :03/07/13 23:18
0,7秒間隔で信号をだすには どう組めばいんでしょか?
>870 スレ違いの悪寒
874 :
デフォルトの名無しさん :03/07/14 11:38
デバッグ中に、 0040128E 8B 8D 50 E5 F9 FF mov ecx,dword ptr [ebp-61AB0h] 00401294 29 C7 sub edi,eax 00401296 01 F7 add edi,esi 00401298 8D B5 54 E5 F9 FF lea esi,[ebp-61AACh] 0040129E 89 7D D4 mov dword ptr [ebp-2Ch],edi 004012A1 8B 7D F4 mov edi,dword ptr [ebp-0Ch] 004012A4 B8 01 00 00 00 mov eax,1 004012A9 01 C3 add ebx,eax 004012AB 89 5D F0 mov dword ptr [ebp-10h],ebx というコードが、0040129Eのmov命令を実行すると 0040128E 8B 8D 50 E5 F9 FF mov ecx,dword ptr [ebp-61AB0h] 00401294 29 C7 sub edi,eax 00401296 01 F7 add edi,esi 00401298 8D B5 54 E5 F9 FF lea esi,[ebp-61AACh] 0040129E 89 db 89h ←変わってる 0040129F 7D db 7dh ←変わってる 004012A0 D4 8B aamb 8Bh ←変わってる 004012A2 7D F4 jge 00401298 ←変わってる 004012A4 B8 01 00 00 00 mov eax,1 004012A9 01 C3 add ebx,eax 004012AB 89 5D F0 mov dword ptr [ebp-10h],ebx ようになってしまうんです。 何かご存知の方がいたらご教授ください。 お願いします。
>>874 IDEのバグじゃないの?
なに使っているか位書かないと。
>$-1 そんな現象出会ったことないよ。 デバッガのバグか、自分のプログラムが悪いと思う。
>875 寂れたスレだと思ってゆっくり書いたら・・・ 割り込まれた!
せめて前後のレジスタの値とかもうちょっと情報を
>>877 すまそ。
漏れも結構時間かけたんだが。
バイナリは変わってないから、バグだと思うけどねえ。
880 :
>>874 :03/07/14 20:26
>>875-879 レスありがとうございます。
すいません、IDEはVisual Studio.net(vc7)です。
レジスタ値は、mov前が
EAX = 0000000F EBX = 00000000 ECX = 00000004 EDX = 0000000D ESI = 007AE2F4
EDI = FFFFFFF4 EIP = 0040129E ESP = 007AE297 EBP = 0080FDA0 EFL = 00000282
CS = 001B DS = 0023 ES = 0023 SS = 0023 FS = 0038 GS = 0000
OV = 0 UP = 0 EI = 1 PL = 1 ZR = 0 AC = 0 PE = 0 CY = 0
mov後が
EAX = 0000000F EBX = 00000000 ECX = 00000004 EDX = 0000000D ESI = 007AE2F4
EDI = FFFFFFF4 EIP = 004012A0 ESP = 00000004 EBP = 0080FDA0 EFL = 00000282
CS = 001B DS = 0023 ES = 0023 SS = 0023 FS = 0038 GS = 0000
OV = 0 UP = 0 EI = 1 PL = 1 ZR = 0 AC = 0 PE = 0 CY = 0
となっています。
元々、Visual Studio6が入っていたのですが、.netを少し使うために、
余計なことを考えずに済むようvmware上にVisual Studio.netを
入れたのですが、VS6上ではこのような現象がおきていないため
vmwareが何か関係しているのかな?と、今は考えています。
もちろんVS7のバグの可能性もあるのですが。。。
>>868 ではないのですが、868のようなジャンプ先アドレスの
異常もあったりしました。vmware上での開発で何か不具合が発生する等
ご存知の方がいればぜひ教えてください。
ありがとうございました。
EIPが2しか進んでいないし ESPがとんでもない値になってるな まあVMwareのバグだろうね
__∧_∧_ |( ^^ )| <寝るぽ(^^) |\⌒⌒⌒\ \ |⌒⌒⌒~| 山崎渉 ~ ̄ ̄ ̄ ̄
883 :
デフォルトの名無しさん :03/07/23 00:26
80x86系でModR/Mバイトがさっぱりわからないのですが、 このあたりの事について初心者向けに詳しく説明した HPはありませんか?
>>883 取り敢えず、そこのMODRMの説明で分からなければ
もう1度、最初から勉強した方が良い
ちょっと解りました。 例えば、 MOV EAX,EBX // 89 D8 は MOV r/m32,r32 なので、OPコードは 89 /r になる。 /r は、命令のModR/Mバイトにレジスタオペランドとr/mオペランドが 入っている事を示す。 ここが??です。 機械語なら俺に質問しろ!スレで、両方がレジスタの時は mod は 11 とあったので、 次の3ビットが転送元のレジスタ(EBX→011) その次の3ビットが転送先のレジスタ(EAX→000) 合わせて 11 011 000 = 0xD8 という事ですか? 答えから過程を導き出していますが…。 MOV AX,BX // 66 89 D8 0x66 はアドレスサイズのプリフィックスだそうです。 ここも??。 MOV [EAX],EBX // 89 18 0x18 = 00 011 000 つまり、 MOV r/m32,r32 において、転送元r32は常にレジスタなので、 ModR/Mバイトの真ん中3bitで転送元のレジスタ(8種類)を指定する。 上位2bitと下位3bitで転送先を指定する。
888 :
デフォルトの名無しさん :03/07/23 02:38
ついでに即値の転送もやってみました。 MOV EAX,0x12345678 の場合は、OPコードが B8+rd 。 +rd 単一のオペコードバイトを形成するために、プラス符号の左に与えられた 16進バイトに追加される0から7までのレジスタコード。 B8 にレジスタEAXを表す 000 を足せばいいのかな? よって、 B8 78 56 34 12 MOV ECX,0x12345678 なら、レジスタECXは001なので B9 78 56 34 12
>>889 よく出来ました。
足すというのはちょっと違うだろと思うけど結果は同じだしな…
ちなみに0x66は32bitの代わりに16bitレジスタ/アドレスを使うということ。
_asm{ mov a,1 } cout a << endl;
この_asmってVC限定なんでしょうか?
>>892-893 OpenWatcom ではVCと同じく _asm
BorlandやDigital Marsでは asm か _asm または __asm
895 :
デフォルトの名無しさん :03/07/24 22:38
char c; _asm mul c とやった場合、AXレジスタに値が入るのですが、16ビットの変数がないため型が合わず、値を受け取れません どうすればいいのでしょうか?
>>895 int ans;
char c;
_asm {
mul c
and eax, 0FFFFh
mov ans, eax
}
とか。
movzxかmovsxでもいいぞ。 それよりも符号付きだからimulつかわんといかんはずだが。
bcc32(5.5.1)を使っているのですが、オプション-rdって機能してますか? コンパイラに、うまく私の気持ちが伝わらず、registerキーワードを使って どの変数をレジスタに割り振って欲しいかをはっきり言おうと思ったのですが この-rdすら無視します(?) switch文のcaseの偏りが見えているので、それを考慮して 割り振らせたいのです…が、特殊な例(case)のところが どうしても他と比べて長くなりがちで、たぶんそれで、 特定の変数の使用回数が増えて、だからレジスタに 割り振っているのだと想像しました その特殊な例の部分を別の関数に掃き出すようにしようかとも 思いましたが…
最近の最適化コンパイラはみんな、プログラマよりも自分のほうが頭がいいと思ってるよ。
そうそう、この前なんか 「( ´,_ゝ`)プッ タブのつもりですか?」 だって。あいつら絶対俺たち舐めてるよ。今度締めなきゃな。
ダメポなのか…
( ´Д`)/ <先生! 8086系のLOOP命令遅いんですが 何か使いみちあるんでしょうか?
>>902 過去の遺物です。
命令長短いのでメモリをけちる時はそれなりに便利。
たしかPentium以降では命令長とか意味無くなったな
μopに変換するPentiumPro以降でもデコードとキャッシュで多少は意味があるかもしれん トレースキャッシュ搭載のPentium4以降ではほとんど意味が無い
>903〜905 アリガd
907 :
デフォルトの名無しさん :03/07/29 16:22
SSE2で「整数の」内積演算のプログラミング をしたいのですが、本がなくてさっぱりわかりません。 例えば、unsigned char a[8] b[8]との内積の和 a[0]*b[0]+a[1]*b[1]+.... をSSE2で書くと、どのようになるのでしょうか。 よろしくお願いします。(_o_) また、MMXで書いたものはあるのですが、 SSE2に直すことでさらなる速度アップは望めるのでしょうか。
910 :
デフォルトの名無しさん :03/07/29 16:45
>>909 ごめんなさい。
もうひとつのC++版でも聞いてしまいました。
そしたら、アセンブラ版に行けばどうかと、アドバイス
もらったもので。
912 :
デフォルトの名無しさん :03/07/29 16:58
版じゃねーよ
914 :
デフォルトの名無しさん :03/07/29 22:05
「アセンブラ板」でした。すみません。
>>907 です。
誰か助けてください。お願いします。
915 :
デフォルトの名無しさん :03/07/29 22:11
「スレッド」だろアホ
「アセンブラスッドレ」でした。すみません。
ノルウェーの外注プログラマさんが書いてきたWindowsアプリ、 大部分がアセンブラだった(;´Д`) スゲー 別のCPUのエミュレーションソフトだから、アセンブラで書いた方が いい部分がたくさんあることは確かなんだが・・・・ (一応アセンブラの他にVC++とVBも使ってましたが・・・ やっぱり向こうの人は凄いんだなぁ。。。
>>917 VBとアセンブラ併用するなんて面白いな
>>916 nasmのマニュアルに全部書いてあるよ。
英語で。
922 :
デフォルトの名無しさん :03/07/30 21:08
>>920 >>921 わお!ありがとうございます。
しばらくマニュアルと格闘してみます。
Visual Studio でSSEを使おうとするだけで、悪戦苦闘でした。
MMXはそのまま使えるのに、SSEは、プロセッサパックなるものを当てなければ
ならない上に、そいつはサービスパック4にしか対応してません。
サービスパック5を当てていた私は、VSのインストールからやり直す羽目に(涙
また、泣きつくこともあるかもしれませんが、よろしくお願いします。
>>922 オイオイ
VS6SP5用のVCPPもあるぞ
925 :
デフォルトの名無しさん :03/07/31 00:13
The Processor Pack requires that you have already installed Microsoft Visual C++ version 6.0 with Service Pack 4 「or greater」.
>>926 それウソだよ。SP5 環境へは適用できない。
SP5 用に vcpp5.exe ってのが別にあります。
929 :
デフォルトの名無しさん :03/07/31 00:30
931 :
デフォルトの名無しさん :03/07/31 07:12
みなさん。ありがとうございました。 なんとか、徐々に動き出しました。 また、よろしくお願いします。
932 :
デフォルトの名無しさん :03/07/31 07:51
未だにincが早いと信じてるアフォども! intelの最適化マニュアルもう一度よく嫁
Pentium4がもっさりなだけだから、心配しなくていいよ
INCはuv命令で1clock命令 LEAが早くなるケースはありえない lea reg1,[reg2+1]とかの状況依存のケース があるとでも言いたいのだろう。
おっと、前提条件がなかったので勝手に Pentiumの話としました
当然ながらPentiumProなら著名例がある INC reg JC adr JCでストールする。
Cマガで最適化の特集をやってたとき、Pen4ではincはどんなときでも避けろと いってたような気がする
↑なんでですの? コードが短いしバリバリ使ってますが・・・
Pen4なんてクロックまかせに速いんだから 最適化なんて興味おきない
(^^)
Pentium4 は add 推奨だっけ。
P4のinc/dec命令ではキャリーを保存するために余分な処理が増えるらしい
PenProと違い、Pen4では inc reg は2μOPS。 add reg,1 ならもちろん1μOPS。 Pen4にとってinc/dec命令はトレースキャッシュや実行ユニットを 無駄に消費する長い命令だ。
なんでそんなアホな設計にしたんですか?
アホだから
incも過去の遺物なんだよ。 ワザワザ使う方がアホ。
アセンブラなんか過去の遺物なんだよ。 時代はBASIC。
952 :
デフォルトの名無しさん :03/08/04 23:01
アセンブラなんか過去の遺物なんだよ。 時代はCOBOL。
アセンブラなんか過去の遺物なんだよ。 時代はPASCAL。
アセンブラより速いといわれるFORTH これからの時代はこれですよ
じゃFORTRANということで −−−−−−−−−−−−修了−−−−−−−−−−−−
いやいやAdaということで −−−−−−−−−−−−再開−−−−−−−−−−−−
やっぱLISPだろ。 LISPマシンならアセンブラは不要だぜ。
やっぱしCということで −−−−−−−−−−−−初恋−−−−−−−−−−−−
わたしDしちゃった −−−−−−−−−−−−妊娠−−−−−−−−−−−−
960 :
デフォルトの名無しさん :03/08/05 17:08
ヽ(`Д´)ノモルァ
このスレッドは胴なしモナーが通り過ぎます。 通り過ぎるだけです、スレには関知しません。 ∧_∧ ∧_∧ ∧_∧ ( ´∀`) ( ´∀`) (´・∀・`) (_⌒ヽ (_⌒ヽ (_⌒ヽ ,)ノ `J ,)ノ `J ,)ノ `J
コートの中身はC++ −−−−−−−−−−−−逮捕−−−−−−−−−−−−
結構昔、Win3.1の人に「MacにはAPIがないから超人じゃないとプログラムが組めない」 とか言われてたのを思い出した。ありがとう。
LAHFって命令「初めての8086」「初めての486」 載ってないのは何で?
>963 (´<_ ` )フーン
自作しなければならないコントロール類が多かったからな。今は知らんけど
RAD厨はコントロールも自作できないのか
だーれもRADの話なんかしてないし
RAD厨は何かとコントロールの話を出すのでRAD厨かと思ったよ
妄想ですか
3DNow!ってMMXの代替? それともSSEの代替?
974 :
デフォルトの名無しさん :03/08/11 23:32
3D Now!について参考になるAMDのマニュアルってどれ? Performanceなんとかというマニュアル?
>>975 AMDのサイトにあるマニュアルのなかでどれが参考になるのか、きいてるのだが。
AMDにあるとわかってるならそれ以上何を聞く必要があるのだ? ちゃんと何のマニュアルかかいてるだろ それでもわからないならせめて全部読むくらいの努力はしような
>>977 全部落とすのが面倒だから聞いてるんだよ。
まあ、聞いてもわからないなら全部落とすけどね。
こんなこと面倒くさがってる奴にアセンブラは無理
たしかにタイトルでわからん奴が内容を理解できるのか疑問 K6-2の頃にあった日本語ドキュメントはなくなってるね まああるだけ無駄だったけど
☆ チン マチクタビレタ〜 マチクタビレタ〜 ☆ チン 〃 Λ_Λ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ヽ ___\(\・∀・) < 次スレまだ〜? \_/⊂ ⊂_ ) \_____________ / ̄ ̄ ̄ ̄ ̄ ̄ /| | ̄ ̄ ̄ ̄ ̄ ̄ ̄| | | 愛媛みかん |/
>>979 無理なわけないがな。w
まあ全部落とすことにするよ。
>>980 タイトルだけじゃ詳しい内容まではわからん。
intelみたいな数十メガバイトの日本語ドキュメントきぼん
984 :
デフォルトの名無しさん :03/08/13 22:49
IA32のアセンブラで質問ですが、 レジスタの内容を一時的に退避して、後で使う場合、 ・push/popを使う場合 push eax ;eaxにデータが格納されている 〜eaxを使う処理 pop eax 〜次の処理 ・あらためてメモリ上の参照元データからレジスタにロードする場合 〜eaxを使う処理 mov eax, DWORD PTR 元データが格納された変数 〜次の処理 どっちが速いんでしょうか? (push/popは2クロック掛かるから不利?)
985 :
デフォルトの名無しさん :03/08/13 23:29
計ってみても明確な差は出ませんでした。 気を使うだけ無駄でしょうか?
push popは2命令あわせて2byte mov reg, [mem]は5〜6byte
push/popはアクセス先がスタックになる スタックは1次キャッシュに乗ってる可能性がかなり高い が、ベンチマークするとどっちもキャッシュに乗るから 差が出ない
>>985 CPUによって当然条件が違うからさ、
後5年くらいしてIA32が完全に枯れてから気を使った方がいい。
まあその頃はIA64で同じような事悩んでるんだろけどね。