Message Log 32 Return to Parent Menu 
Last Updated by 07/01/05(Fri)  

 
Tips
 

 やっぱり 2001 年もアセンブラッ!!だねっ


 
Message log list
 

 アセンブラ掲示板に書き込まれた過去のログです。


Message log 44 (05/01/0506/30/05)
Message log 43 (01/01/0504/30/05)
Message log 42 (01/01/0412/31/04)
Message log 41 (11/01/0312/31/03)
Message log 40 (10/01/0310/31/03)
Message log 39 (04/01/0309/30/03)
Message log 38 (12/01/0203/31/03)
Message log 37 (08/01/0211/30/02)
Message log 36 (05/01/0207/31/02)
Message log 35 (03/01/0204/30/02)
Message log 34 (01/01/0202/28/02)
Message log 33 (09/15/0112/31/01)
Message log 32 (08/01/0109/14/01)
Message log 31 (05/26/0107/31/01)
Message log 30 (05/15/0105/25/01)
Message log 29 (05/01/0105/14/01)
Message log 28 (02/01/0104/30/01)
Message log 27 (01/01/0101/31/01)
Message log 26 (10/01/0012/31/00)
Message log 25 (07/21/0009/30/00)
Message log 24 (06/16/0007/20/00)
Message log 23 (05/20/0006/15/00)
Message log 22 (05/01/0005/19/00)
Message log 21 (04/01/0004/30/00)
Message log 20 (02/01/0003/31/00)
Message log 19 (01/01/0001/31/00)
Message log 18 (11/01/9912/31/99)
Message log 17 (09/05/9910/31/99)
Message log 16 (08/21/9909/04/99)
Message log 15 (07/01/9908/20/99)
Message log 14 (04/01/9906/30/99)
Message log 13 (02/01/9903/31/99)
Message log 12 (11/01/9801/31/99)
Message log 11 (09/21/9810/31/98)
Message log 10 (08/01/9809/20/98)
Message log 09 (07/01/9807/31/98)
Message log 08 (05/04/9806/30/98)
Message log 07 (04/08/9805/03/98)
Message log 06 (02/23/9804/07/98)
Message log 05 (01/01/9802/22/98)
Message log 04 (11/09/9712/31/97)
Message log 03 (10/17/9711/08/97)
Message log 02 (08/22/9710/16/97)
Message log 01 (06/20/9708/21/97)


 
Message log 08/01/0109/14/01
 




.db  [2001/09/14 Fri 11:17:58]  [202.224.108.70]

こんにちは。 .db です。

>FM 音源系の割り込みの問題と混同していました。すみません。

いいえ。FM 音源の割り込み時には注意が必要なのですね。

>もしかして、CRTV 割り込み処理で IN AL,41H していませんか?

していませんでした。
割り込みベクタ FD80:~ のベクタの飛び先が
IRET なのは、 BIOS と RAM の違いなのか調べています。
まだ未解決なのです。
ではまた。

笑む獅子  [2001/09/12 Wed 15:13:42]  [210.154.48.58]

-TechnicalAssembler-
MASM32が違法だとか,本物が有料だとか,年間契約だとか,別物が制限つきだとか,さっぱりこんがらがった.
結局 .EXE の構造さえ網羅できれば,バイナリプログラミングも夢ではないですね.
なんでもMSから買わずに済むようですな.

澤口先生もっと御教授を御願い致します。
>マシン語です。
>ただし、処理系が独自に構成するので、
>例えば VC++ の lib ファイルがそのまま gcc や Borland C++ でリンクできるとは限りません。

1._く、詳しく知りたいのれす。バイナリレベルでの違いはどうなってるにょぉ?
2._「処理系」とは如何なる物でございましょうか。
3._逆アセンブラ「xda」を信じる糧を私は知り得ません、
___vbではp-codeと称する.exeを作ると言いますがこれを逆汗しても無意味と言う事ですか?
___さらに文章ファイルまでも逆汗したらアセンブリがでてきました。

もし、澤口先生の逆鱗に差し支えなければ御指導の程を宜しく御願い致します。
ロコ  [2001/09/10 Mon 09:33:05]  [202.15.16.35]

皆さんありがとうございます。
Mistyさん>実行速度という視点から見ていたのではなかったのですが、やはりパイプなどは絡んできますが・・・
アスキーのX86シリーズでペンティアムが出ればいいのに・・・
しろさん>TDの情報ありがとうございます。
英語なので”disassem”というメニューが無かったので逆アセは無いのかと思っていました。Cマガにちょこっとだけ情報があったと思ったので見直してみます。
EILさん>ありがとうございます。デバロッパ・マニュアルは検索してしおりを眺めただけなのでそこまでは見ていませんでした。
見てみます。
ロンリークリチャーさん>情報ありがとうございます。
早速見てみます。

みなさんありがとうございました。一応過去ログにあったURLも書いておきます。 <a href=藤波さんの趣味のページ>http://www.sonycsl.co.jp/person/fnami/asm.htm</a>

AF  [2001/09/09 Sun 23:06:23]  [210.233.166.92]

間違い訂正です。

> >そうそう、windows 98 の DOS 窓で CRTV 引っ掛けて
> >常駐すると、コマンドプロンプト A:\> に戻った瞬間に
> >割り込みが止まることがあります。これを防ぐには
> >かなりトリッキーな事が必要です。
>  windows98 に対応するために、概要だけでもお願いできるでしょうか?

これ自分が勘違いしていました。CRTV 割り込みが止まること
は無いようです。FM 音源系の割り込みの問題と混同してい
ました。すみません。

> ところが、ドスのキーボード bios のキーコードでは、前の書き込みの
>  CRTV 割り込みでも取りこぼしがありませんでした。

もしかして、CRTV 割り込み処理で IN AL,41H していませんか?



ロンリークリチャー  [2001/09/09 Sun 21:47:42]  [203.165.3.88]

ここなどはどうでしょう。
クロック数について
http://www.mirai.ne.jp/~mitsuman/mag/asm.html
EIL  [2001/09/08 Sat 21:40:37]  [61.125.80.138]

はじめまして。

P6アーキテクチャのクロック数はデベロッパーズマニュアルに
載っていると思うのですが、
多分にわかりにくいと思います。

P6はx86命令をμオペコードと呼ばれる単純命令に分解します。
そのμオペコードはバッファにプールされ、
(元のx86命令の順序に関わりなく)
実行できるところからどんどん実行されていきます。

というような説明は上巻の「アーキテクチャの説明」のようなところを見ないと
分からないようにできているはずです。

で、命令クロックですが、
命令デコーダの効率、あるx86命令の変換後のμオペコード数、
μオペコードの実行効率、分岐予測などが関わってきますが、
概算するのはそう難しいことではないように思います。
完全に正確なクロックはPCでは不可能ですが、
最適化の際の目安ぐらいにはなるでしょう。

これらはデベロッパーズマニュアルと最適化マニュアルにほとんど載っています。
なかなかの分量ですが、簡潔にまとめたサイトは、、、知らないですねぇ。(-_-;
じっくり読んで見てください。(^^;
しろ  [2001/09/08 Sat 16:05:24]  [210.253.200.192]

ロコさん、こんにちは。

>(TDB)など)では逆アセンブルはできないのでしょうか?
TDBとは Borland が現在フリーソフトとして公開している Turbo Debugger
(TD32.EXE)のことでしょうか? Turbo Debugger は逆アセンブル機能を持
っています。

Pentium の命令のクロック数に関しては数年前にでた書籍で見たことがあ
りますが、Web 上では私は見たことがありません。
(書籍も数年前のものなので、Pentium II 以降に関しての記述はありませ
んでしたし、入手困難かもしれません)
misty  [2001/09/08 Sat 15:39:30]  [211.16.189.79]

586/686の実行クロック。

パイプが増えてるので、単純な計算では出てこないと思われ。
(分岐予測ミスがどの程度の頻度で出るかって問題です。)
要はコーディングによって実質ステート数は可変です。
またキャッシュの効果も絶大なので、実時間自体ばらつきが
生じます。

#586以降はそれまでハードロジックで書いてた部分の何割かを
ソフトウェア的に展開して実行してるんではなかったかな。
(部分的にRISC風な設計にしてあったはず。)

ついでに。Microsoftのコンパイラも部分的にインタプリタ併用
する仕様になっていたんではないかと。(確かMSC5.1から)

シビアに実行時間を規制するのであれば、何らかの外部トリガを
使用するのが吉かと思われます。

---

笑む獅子さん。

> 16ビットコンピュータと32ビットコンピュータの違いとは?

CPUのビット幅は、かつてはアドレスバスを表していたと
思ったのですけども、MC68008やi8088などの頃からは
物理的なバスが8ビットでも内部アーキテクチュアが
16ビット(つまり16ビット演算が可能)であれば16ビット
と云う様になりましたね。

#あ、HD64180なんかはこの逆パターンすね。

な訳でアキュムレータが16ビットなら16ビットCPUで、
32ビットなら32ビットCPUとなっているはずです。

> ソフト全般を作り直さなきゃ行けないのはナゼなぜ?

ビット幅が変わると云う事は、前述した通りレジスタ幅も
拡大されると云う事なのです。分岐命令や演算命令はじめ
ほぼ全面的に影響が出ますね。
『似た』ソースで書けても、吐き出されるコードは別物と
考えておくべきでしょう。
.db  [2001/09/08 Sat 13:12:18]  [202.224.108.87]


 こんにちは。 .db です。

>こんなもんでどうでしょう
>CRTV 中に KB の割り込みマスクをいじるのは良くありません。
>sti を忘れているせいではないですか?

 sti などはつけたり外したりしましたが、改善されませんでした。
 KB 割り込みのマスクはいじらないことにします。
  eoi を送るか、マスクを付けるか、出来る事は少ないので、その流れを変更するなどを、
 一通り試しましたが、改善されませんでした。

 ところが、ドスのキーボード bios のキーコードでは、前の書き込みの
 CRTV 割り込みでも取りこぼしがありませんでした。
 だから、 CRTV 割り込みではなく、キーボード割り込みに問題があるようなのです。

 ドスのキーボード割り込みベクタの飛び先を参照したところ驚いたのですが、
 何も処理せず iret のみでした。

 ドスのキーボード処理との衝突が、関係するから取りこぼしが発生すると思ったのですけど、
 ドスのキーボードは何の割込みでされているのでしょうか?

 関係のありそうな int 18h のベクタの飛び先を iret のみに変更してみたのですが、
 取りこぼしを改善されませんでした。


>そうそう、windows 98 の DOS 窓で CRTV 引っ掛けて
>常駐すると、コマンドプロンプト A:\> に戻った瞬間に
>割り込みが止まることがあります。これを防ぐには
>かなりトリッキーな事が必要です。

 windows98 に対応するために、概要だけでもお願いできるでしょうか?

 ではまた。

AF  [2001/09/07 Fri 23:54:44]  [210.233.166.95]

.db さんこんにちは、

> 何故か取りこぼしてしまいます。
> 取りこぼしをなくすことはできますか?

こんなもんでどうでしょう
動くかどうかは試していない (^^;)

inworkflag db 0 ;CS に置いてください

HandleCrtv proc far
push ax
in al,02h
or al,4h ;Disable CRTV
out 5fh,al ;wait
out 02h,al
mov al,020h
out 5fh,al ;wait
out 00h,al ;SEND EOI
mov al,1h
lock ;マルチプロセッサの 98 って有るみたい
xchg [cs:inworkflag],al ;再入対処(恐らく再入は無いはずだけど)
test al,al
jnz @@skip
sti
ここに処理を入れる
cli
mov al,00
mov [cs:inworkflag],al
@@skip:
in al,02h
and al,-1-4h ;Enable CRTV
out 5fh,al
out 02h,al
out 64h,al ;Reset crtv-int. ff
pop ax
iret
HandleCrtv endp

CRTV 中に KB の割り込みマスクをいじるのは良くありません。
sti を忘れているせいではないですか?
割り込み処理に入った直後は cli 状態です。h/w int に
pushf, cli, tf=0 相当の処理が含まれ、 iret に popf
相当が含まれます。

CRTV 処理はなるべく早く終わらせた方が何かと良いです。
CRTV 周期ギリギリだったり、これを超えるとぎこちなく
なります。特に画面などに小さいアニメを表示すると
きなんかはフィーリングが違います。

そうそう、windows 98 の DOS 窓で CRTV 引っ掛けて
常駐すると、コマンドプロンプト A:\> に戻った瞬間に
割り込みが止まることがあります。これを防ぐには
かなりトリッキーな事が必要です。

.db  [2001/09/06 Thu 20:38:41]  [202.224.108.113]


 こんにちは。.db です。
PC9801 で CRTV 割り込み中に重たい処理を行うと、
CRTV 割り込み中にキーボード割込みのマスクを許可しても、
何故か取りこぼしてしまいます。
取りこぼしをなくすことはできますか?

crtv_int: ; CRTV の割り込みの開始
push ax
in al, 2
and al, 0f9h ; CRTV とキーボードの割込みマスクを許可します。
out 2, al

mov al, 20h ; eoi
out 0, al
out 64h, al ; CRTV
pop ax
; 〜CRTV 割り込み処理をします
iret

 pc9801 の適切な掲示板があったら教えてください。
 ではまた。




ロコ  [2001/09/04 Tue 16:54:23]  [202.15.16.35]

 こんにちは。
検索サイトよりやってきました。
ちょっとしたプログラムを書いていて不思議に思ったのですが、
各コンパイラやオプションによって吐き出されるアセンブラのソースが
違うのはいいとして、命令(pop add callなど)に何ステート(クロック)使用するのかは調べられないのでしょうか?
たとえばGDBでは各関数を逆アセンブルすることで命令が何バイト使っているのかがわかるのですが他の処理系(VC++ BCC(TDB)など)では逆アセンブルはできないのでしょうか?

また、各命令が何ステート(クロック)使用しているのかを調べるためインテルのPVのマニュアル(インテル・アーキティクチャ・ソフトウェア・デベロッパーズ・マニュアル)を見たのですが、それらしいことは書いてありませんでした。またここの過去ログを見たのですがlog15にあったページへリンクがありましたが80486まででした。

質問が1命令 nクロック数ということと1命令 nバイトということと混じってしまっているのですが、できればクロック数、バイト数両方について理解を助けてもらえるURLを教えていただきたいと思います。
笑む獅子  [2001/09/04 Tue 12:54:21]  [210.154.48.58]

おひさし、おひさし。

16ビットコンピュータと32ビットコンピュータの違いとは?
ソフト全般を作り直さなきゃ行けないのはナゼなぜ?

Windows64bit
Linux64bit
.db  [2001/09/04 Tue 11:13:30]  [202.224.108.60]

こんにちは。 .db です。

>Pentium II/III/4
>だと前後の命令並びも加味したら div 命令(もしかしたら
>fdiv)に負けるかも。

 最新の CPU によっても結果が異なるようですね。
 紹介されたページを参考にしてみます。

>最適化の細かい話はこのサイトがお勧め。
>http://homepage1.nifty.com/herumi/

 興味深いサイトですね。参考になりそうです。
 ご返答ありがとうございました。



.db  [2001/09/04 Tue 11:12:46]  [202.224.108.60]


ご回答を参考に、必要になった 16 ビット版の 9 ビットの商を求めてみました。
更に簡潔に小数部多めに計算できるでしょうか...。
;
;IN
; ax : 80 で割られる数
;RETURN
; ax : 商 0~ 255
;BROKEN
; ax, dx

shr ax, 1
add ax, ax
mov dx, ax
shr dx, 1
add ax, dx
shr dx, 1
shr dx, 1
add ax, dx
shr ax, 1
shr ax, 1
shr ax, 1
shr ax, 1
shr ax, 1
shr ax, 1
shr ax, 1

最初は以下の少数部 8bit だと簡潔だったのですが。

add ax, ax
add ax, cx
xchg ah, al
xor ah, ah

なべちゃん@abk  [2001/09/04 Tue 02:49:55]  [210.252.157.23]

↓80で割ると決まってるなら、予め計算したおいて
定数を積算(mul)した後、上位32bitに相当する edx を取り出すのが
ベストかと。

最適化の細かい話はこのサイトがお勧め。
http://homepage1.nifty.com/herumi/
「刹那におけるささやかな考察」や
「せっかちな人々」(BBS)などを参照のこと。

# そういやさのサイトも長いこと顔だしてないなぁ(汗

AF  [2001/09/04 Tue 01:10:59]  [210.233.166.75]
http://www.ksky.ne.jp/~afuruta/

> 200/ 80 の場合では、 200/ 64=3.125 , 200/ 16=12.5 とした後で、
> どうするとよいのでしょうか?

80 で割るのってちょっと大変
逆数を使う方法を示しておきます。ほかにも方法があると思う。

;IN
;eax: 80 で割られる数
;RETURN
;eax: IN の eax を 80 で割ったあと 65536 倍した値)
;ただし、逆数で乗算しているので真値より少し小さい値になる。
;80 の逆数を 2 進数で表すと循環小数になる。
;BROKEN
;edx

lea eax,[eax*2+eax]
mov edx,eax
shl edx,4
add eax,edx
shl edx,4
add eax,edx

より真値に近づけるためには四捨五入相当の処理をしてください。
小数点以下をもう少し多めに計算したほうがいかも。

基本的には並列に計算できない処理です(ハードウェア
ゲートで組むとかなら別かもしれない)。遊んでしまうハイプ
(演算ユニット)が増えてしまいます。Pentium II/III/4
だと前後の命令並びも加味したら div 命令(もしかしたら
fdiv)に負けるかも。


.db  [2001/09/03 Mon 10:50:09]  [202.224.108.252]

>sar eax, n ; eaxを2^nで割る(符号あり)
 シフト命令を合わせて 2 以外で割る場合が不明だったのです。
 200/ 80 の場合では、 200/ 64=3.125 , 200/ 16=12.5 とした後で、
 どうするとよいのでしょうか?
 よろしくお願いします。

Ichi  [2001/09/03 Mon 00:01:55]  [211.13.1.228]
http://isweb7.infoseek.co.jp/computer/ichi98/

>ところでまた質問なのですが、mul を使用せずに2の乗数で乗算をすると高速化できますが、
>div を使用せずに除算を高速化することはできるのでしょうか?

sar eax, n ; eaxを2^nで割る(符号あり)
shr eax, n ; eaxを2^nで割る(符号なし)
and eax, 2^n - 1 ; eaxを2^nで割った余りを得る

でできます。
(負の数は、余りが正になるように除算されます)
HAT  [2001/09/02 Sun 16:34:48]  [61.211.97.104]

澤口@一升金さん、早速のレスありがとうございます。
日本語のHPばかり検索していました。
大変助かりました。
本当にありがとうございました。
.db  [2001/09/02 Sun 13:18:45]  [202.224.108.157]

>皆様で、よい情報や書籍などご存知な方はおられないでしょうか?

つい最近教えていただいたのですが、こちらなどは日本語なのでたいへん判りやすいです。
http://www.caffeine.jp/~cafe/ns/index.html
ゲームラボと言う雑誌にも載っていたそうです。

 ところでまた質問なのですが、mul を使用せずに2の乗数で乗算をすると高速化できますが、
 div を使用せずに除算を高速化することはできるのでしょうか?
 よろしくお願いします。

澤口@一升金  [2001/09/02 Sun 02:07:09]  [211.2.146.37]

澤口@一升金です。

to HATさん:

Web 検索をかけてみました。

お家元の MS社による FAT32 の解説。

http://www.microsoft.com/hwdev/hardware/fatgen.htm

ここらにも解説がありました。

http://home.att.net/~rayknights/pc_boot/w98bboot.htm
http://www.teleport.com/~brainy/fat32.htm

著作物ですと、吉野敏也氏の「Windows95 OSR2の秘密」あたりに
解説があるんじゃなかったかと思います。
HAT  [2001/09/01 Sat 00:27:20]  [61.211.97.104]

はじめまして。

アセンブラなどでHDD等を直接制御したいのですが
FAT16についての資料しか入手できません。
FAT32について詳しく書いてある資料とか
ご存じの方がいらっしゃいましたら、
ご教授願えませんでしょうか。
よろしくお願いいたします。
AC-YOUCH  [2001/08/31 Fri 14:30:58]  [210.251.192.4]

やまたけさん、こんにちわ。

>色々、書籍を探してみたのですが、全く見つかりません。

6502(6280でも構わないなら)
「でべろ スターターキット アセンブラ編」(徳間インターメディア)が、
比較的入手しやすいかと...
昨年の話ですが、秋葉原の書泉タワーとLAOXゲーム館(共に 何故か攻略本コーナー)で
見かけました。
あとCが読めるならソース公開されているエミュレータの6502コアを見てみるのも
手かも知れません。

.db  [2001/08/30 Thu 14:03:45]  [202.224.108.131]


>経験則です。いや私もよくするんですよ。
>バグに悩んで、一生懸命ASMソースを追って「なぜだぁーー」と
>数時間〜(ときに)数日つぶすと、一番基本的なところでミスってたり。
>(引数受け渡しとか、データの記録ミスとか、無論ベクタ設定ミスも)
>人間、こんな簡単なところでミスらないよ、というところでミスを犯すと
>間違えそうなところばかりに目がいくようです(汗

 これも経験則ですが、取るのに時間の掛かかるバグというのは、
 つまらないバグの方が多いように思えます。
#つい最近では、 mov ax, cs:[bx] を mov ax, cs;[bx] など、いくらでもでてくることです。

 あれから書き込みをせずにすみませんでした。
 ではまた。

なべちゃん  [2001/08/15 Wed 18:16:03]  [202.236.152.84]

>まさかそんなミスをするとは思わなかったのですが、

経験則です。いや私もよくするんですよ。
バグに悩んで、一生懸命ASMソースを追って「なぜだぁーー」と
数時間〜(ときに)数日つぶすと、一番基本的なところでミスってたり。
(引数受け渡しとか、データの記録ミスとか、無論ベクタ設定ミスも)

人間、こんな簡単なところでミスらないよ、というところでミスを犯すと
間違えそうなところばかりに目がいくようです(汗

.db  [2001/08/13 Mon 11:33:10]  [202.224.108.137]

>再度取得して、予め保存した値と比較してみるといいかも知れません。

 まさかそんなミスをするとは思わなかったのですが、
 確認したところそのとおりだったです。
 前処理で値の設定、後処理で値の取得としていました。
 後処理でも設定したところ無事動作しました。
 質問しなければ、まったく思いつきませんでした。ご返答ありがとうございました。>なべちゃん

 ではまた。

なべちゃん  [2001/08/12 Sun 17:02:25]  [210.252.157.23]

>pc9801 でドスのファンクション( 25h, 35h )からキーボードの割込みを設定し
>元に戻しドスに戻ると、キーボードが無効になってしまいます。

考えられることとすると、ちゃんと元に戻してますか?
再度取得して、予め保存した値と比較してみるといいかも知れません。

そうでないとすると、キーボード割り込み要因クリアという I/O を
たたいていますか?
あぅ、PC-98 の場合それが必要か不明だ。誰かフォローを(汗)

まぁ一番無難なのは、
元々の割り込みルーチンに chain (つなぐ)ようにプログラムを変更することです。

.db  [2001/08/12 Sun 15:36:15]  [202.224.108.51]

こんにちは。 .db です。
pc9801 でドスのファンクション( 25h, 35h )からキーボードの割込みを設定し元に戻し
ドスに戻ると、キーボードが無効になってしまいます。
    eoi というのを送信したり、キーバッファをクリアを試しましたが、有効にできません。
キーボードを再び有効にできるのでしょうか?
また、pc9801 プログラミングの質問掲示板などは、ネットにあるのでしょうか?
よろしくお願いします。

やまたけ  [2001/08/12 Sun 02:56:01]  [63.12.241.47]

はじめまして
この度、7年のブランクを超えて6502のプログラムを組む事になりました。
6502はPCエンジン以来で、しかもその時以来プログラムから離れていました。
PCに88MRの5インチディスクをつけ、過去のソースを引っ張り出したのですが
如何せん、各ニーモニックでのキャリーの動きや、アドレッシングの大半を忘れています。
プログラムを組む楽しさはすぐに思い出したのですが…

色々、書籍を探してみたのですが、全く見つかりません。
皆様で、よい情報や書籍などご存知な方はおられないでしょうか?
又ブランクが長かったため、今のアセンブラ開発環境がどのようになっているのかも、只今模索中です。
(エディターはPeggyを落としてきたのですが、使いやすいですね)

勝手ですがもしよろしければお教え下さい。


マキ志摩  [2001/08/12 Sun 00:32:53]  [143.90.219.5]

もう一度98でCOPY CON <FILE> を
やってみたんですが、
どうやら、Ctrl-Zが付加されるようです。
寝不足で幻覚を見ていたようです。
さー様、なべちゃん様、ありがと御免。

ロンリークリーチャー  [2001/08/11 Sat 06:55:23]  [203.165.3.86]

さーさん:
できました!
ありがとうございます。
まず、簡単な例で等価な命令を作ってから変換したら出来ました。
reverse関数は最適化なしのC言語より2倍近く速かった。
VCで最適化すると変わらないのかな?

あと、インラインアセンブラを何かの関数の中に埋直接埋め込む場合、
eax,ebx,ecx,edx,edi,esiを退避と復帰しないと、
だめですよね?
→混合モードで見たら、退避、復帰のコードが見つからなかったもので。(^^;
下の場合は関数内で完結しているので、
VCが勝手に補ってくれるんでしょうけど、どうなんでしょう。


(1)ローカル変数の場合
void CMyAsmLib::swap_t(unsigned char c1, unsigned char c2)
{
//ローカル
unsigned char temp = c1;
c1 = c2;
c2 = temp;

//等価なインラインアセンブラ
__asm{
mov al,c1
mov temp,al

mov cl,c2
mov c1,cl

mov dl,temp
mov c2,dl
}
}
(2)参照渡し
void CMyAsmLib::swap_s(unsigned char &s1, unsigned char &s2)
{
//参照渡し
unsigned char temp = s1;
s1=s2;
s2=temp;

//等価なインラインアセンブラ
__asm {
mov eax ,dword ptr [s1]
mov cl ,byte ptr [eax]
mov byte ptr temp,cl

mov edx,dword ptr [s1]
mov eax,dword ptr [s2]
mov cl,byte ptr [eax]
mov byte ptr [edx],cl

mov edx,dword ptr [s2]
mov al,temp
mov byte ptr [edx],al
}
}
(3)ポインタ
void CMyAsmLib::swap_p(unsigned char *p1,unsigned char *p2)
{
//ポインタ
unsigned char temp= *p1;
*p1 = *p2;
*p2 = temp;

//等価なインラインアセンブラ
__asm {
mov eax ,dword ptr p1
mov cl ,byte ptr [eax]
mov byte ptr temp,cl

mov edx,dword ptr p1
mov eax,dword ptr p2
mov cl,byte ptr [eax]
mov byte ptr [edx],cl

mov edx,dword ptr p2
mov al,temp
mov byte ptr [edx],al
}
}
(4)最終的なreverse関数
void CMyAsmLib::reverse(unsigned char a[], int begin, int end)
{
//インラインアセンブラ
unsigned char a_temp;//この場合はbeginで置き換えてもよい
__asm{
/*
ecx→loopカウンタ
esi→begin++
edi→end--
eax,ebx,edx→使える
*/
mov eax ,begin
mov ebx ,end
mov esi ,eax
mov edi ,ebx
mov ecx ,ebx
sub ecx ,eax
shr ecx ,1
cmp ebx ,eax
jbe END_FUNC
LOOP_HEAD:
mov eax ,dword ptr a
add eax , esi
mov dl ,byte ptr [eax]
mov a_temp ,dl /*registerが足りない*/
/*mov a_temp,mov byte ptr [eax] と書けない*/

mov ebx ,dword ptr a
add ebx , edi
mov dl ,byte ptr [ebx]

mov byte ptr [eax],dl
mov dl,a_temp
mov byte ptr [ebx],dl/*registerが足りない*/
/*mov byte ptr [ebx],a_temp と書けない*/
inc esi
dec edi
loop LOOP_HEAD
END_FUNC:
}
}
なべちゃん  [2001/08/11 Sat 01:09:35]  [202.236.152.84]

私の出番もなさげですが(苦笑) 少し昔話を。

copy con <file> は昔エディタを知る前はよくやりました。
まぁ、config.sys とか autoexec.bat を1行書き換えるたびに
全部書き直すというのは大変な作業でしたが(苦笑

そのこと、Ctrl-Z が付加されたような覚えがあるんですけど、
またあとでためしてみます。

私は DOS3.1 (non NEC なので 3.3 ではない)からパソコンを
触りだしたのですが、この頃使ってたエディタとかは
Ctrl-Z を付加するものが一般的でした。
途中からは、設定を変更してわざと付加しないようにしてたのを覚えてます。

エディタによっては、テキストの始まりから Ctrl-Z までを
文章と認識してたぐらいですから。Ctrl-Z のないファイル開くと
保存時につけてくれたんですね。
[EOF] とか表示するビュアーもありましたねぇー。

#ああ、なつかしいなぁ

っで、ファイルの終わりを検出するなら、
DOS function のファイルからの読み込みで、「読み込むデータがない」
という状態ですから、ファンクションリストを参照ください。

さ〜  [2001/08/10 Fri 16:31:33]  [165.93.176.178]

ロンリークリーチャーさん:

あ・・・気づきませんでした。
というか、配列の範囲チェックは
いらないのでわ?

さて、
mov al,byte ptr [a+esi]
がどのようなコードとして吐かれるかというと
mov al,byte ptr a[ebp+esi]
になります。a+ebpでaのアドレスが
得られるわけなので、ここから配列
アクセスされることになります。
問題なのは間接参照ではなく、直接参照な点です。
ということはasm部を実行後にbeginとendが
書き換わっていることで確認できます。
配列の先頭アドレスを直接参照しているなら
問題ないのでローカルな配列の先頭要素なら問題ないわけです。
ロンリークリーチャー  [2001/08/10 Fri 11:26:07]  [203.165.3.86]

さーさん:

mov eax ,begin
mov ebx ,end
mov esi ,eax /*begin*/
mov edi ,ebx /*end*/
mov ecx ,ebx /*ecx =end*/
sub ecx ,eax /*ecx =end-begin */
shr ecx ,1 /*ecx =(ecx-begin)/2*//*ecxが0になるまでloop*/

a[11]の場合
int begin =0
int end =10
要素数11ですので (11-0)/2=5回
ですので、ループ回数は正しいと思うのですが??。
ローカルでは配列を操作できる((1)参照)のですが、
配列を渡した場合に、配列の操作が反映されていない((2)参照)ようなのですが。

(1)
/*ローカル変数のreverseはできている*/

void CMyAsmLib::reverse_local(){

int begin =0;
int end =10;
unsigned char b[11];
for(int i=0;i<=end;i++){
b[i]=i;
}
//b=>{0,1,2,3,4,5,6,7,8,9,10}

__asm{
mov eax ,begin
mov ebx ,end
mov esi ,eax
mov edi ,ebx
mov ecx ,ebx
sub ecx ,eax
shr ecx ,1
cmp ebx ,eax
jbe END_FUNC2
LOOP_HEAD2:
mov al,byte ptr [b+esi]
mov bl,byte ptr [b+edi]
            cmp end ,esi /*end>esiなら終了*/ /*配列の範囲チェック*/
jl END_FUNC
cmp end ,edi /*end>ediなら終了*/ /*配列の範囲チェック*/
jl END_FUNC
mov byte ptr [b+edi],al
mov byte ptr [b+esi],bl
inc esi
dec edi
loop LOOP_HEAD2
END_FUNC2:
}

//b=>{10,9,8,7,6,5,4,3,2,1,0}
}

(2)
しかし、配列を渡した場合は、その配列は変更されていない。

void CTesssDlg::OnButton()
{
unsigned char a[11];
int begin=0;
int end =10;
for(int i=0;i<=end;i++){
 a[i]=i;
}
// a=>{0,1,2,3,4,5,6,7,8,9,10}

CAsmTest test;
test.reverse(a,begin,end);

// a=>{0,1,2,3,4,5,6,7,8,9,10}

//a[0]〜a[10]の内容は変更されていない。→やばそう?
}

CAsmTest::reverse(unsigned char a[],int begin,int end)
{
//c言語
/*
unsigned char temp;
while(end>begin){
temp=a[begin];
a[begin++]=a[end];
a[end--]=temp;
}


*/
__asm{
mov eax ,begin
mov ebx ,end
mov esi ,eax /*begin*/
mov edi ,ebx /*end*/
mov ecx ,ebx
sub ecx ,eax
shr ecx ,1
cmp ebx ,eax
jbe END_FUNC
LOOP_HEAD:
mov al,byte ptr [a+esi] /*al = a[esi]*/
mov bl,byte ptr [a+edi] /*bl = a[edi]*/
cmp end ,esi /*end>esiなら終了*/ /*配列の範囲チェック*/
jl END_FUNC
cmp end ,edi /*end>ediなら終了*/ /*配列の範囲チェック*/
jl END_FUNC
mov byte ptr [a+edi],al /*a[edi]=al*
mov byte ptr [a+esi],bl /*a[esi]=bl*/
inc esi /*begin++*/
dec edi /*end--*/
loop LOOP_HEAD
END_FUNC:
}

}

さ〜  [2001/08/10 Fri 09:04:42]  [165.93.176.178]

ロンリークリーチャーさん:
それは、reverseしすぎだからです。
終了条件が違うので見直してみてください。

for(i = 0; i < end; i ++)
a[i] = a[(end-1) -i];

ではうまくいきませんよね?
#原因は1ステップずつ状態を追うとわかります
がんばってください。
ロンリークリーチャー  [2001/08/10 Fri 02:33:33]  [203.165.3.87]

さ〜さん:
さっそくreverseを修正してみました。
しかし、reverseを呼び出しても a[0]〜a[10]の内容が
置き換わっていなかったのですが、
どうすればよいのでしょうか?

void CTesssDlg::OnButton()
{
unsigned char a[11];
int begin=0;
int end =10;
for(int i=0;i<=end;i++){
a[i]=i;
}
CAsmTest test;
test.reverse(a,begin,end);
//a[0]〜a[10]の内容は変更されていない。
}

CAsmTest::reverse(unsigned char a[],int begin,int end)
{
//c言語
/*
unsigned char temp;
while(end>begin){
temp=a[begin];
a[begin++]=a[end];
a[end--]=temp;
}


*/
__asm{
mov eax ,begin
mov ebx ,end
mov esi ,eax /*begin*/
mov edi ,ebx /*end*/
mov ecx ,ebx
sub ecx ,eax
shr ecx ,1
cmp ebx ,eax
jbe END_FUNC
LOOP_HEAD:
mov al,byte ptr [a+esi] /*al = a[esi]*/
mov bl,byte ptr [a+edi] /*bl = a[edi]*/
cmp end ,esi /*end>esiなら終了*/
jl END_FUNC
cmp end ,edi /*end>ediなら終了*/
jl END_FUNC
mov byte ptr [a+edi],al /*a[edi]=al*
mov byte ptr [a+esi],bl /*a[esi]=bl*/
inc esi /*begin++*/
dec edi /*end--*/
loop LOOP_HEAD
END_FUNC:
}
}
マキ志摩  [2001/08/10 Fri 02:31:23]  [143.90.219.122]

さ〜さんへ
copy con <filename>やってみました。
Win98SEのドス窓と98のDOS3.3Cでもやって
みましたが、Win2kと同じく、
Ctrl-Zは付加してくれないようです。
バイナリエディタでCtrl-Zの0x1A書き込んで、
やって行くことにしました。
テキストエディタで見ると・(中黒)になってます。
情報ありがとです。
さ〜  [2001/08/10 Fri 00:29:46]  [210.174.139.246]

マキ志摩さん:
DOSだったら
copy con <filename>
で内容を書いてCtrl+Zで終了するとEOFがついたような
気がします。Win2kのcmd.exeで試したところ、
つきませんでしたが。

ロンリークリーチャーさん:
begin/endを格納しているeax/ebxを
al/blの読み出しでつぶしているようですが。
マキ志摩  [2001/08/10 Fri 00:08:16]  [143.90.219.1]

なべちゃん@abkさんありがとです。
レスを参考に調べなおしたところ、
どうにか解決しました。
CP/Mとの互換性のためMS-DOS1.XXの頃らへんで
Ctrl-Zを入れていたらしいですが、
その後、なくなっていったとは。
どうりで、MS-DOS3.3にはそのようなものはないわけです。
MS-DOS1.XXの頃のエディタならCtrl-Zをつけてくれる
ものもあるというわけですね。
多謝
ロンリークリーチャー  [2001/08/09 Thu 19:42:56]  [203.165.3.87]

VCのインラインアセンブラで配列を扱いたいのですが、
デバックバージョンでは問題ないのですが、
リリースバージョンで強制終了させられてしまいます。
(reverseは配列の中身を逆転させる関数です。)
どこがいけないのか見当がつきません。
どなたか助けて〜。

void CTesssDlg::OnButton()
{
unsigned char a[11];
int begin=0;
int end =10;
CAsmTest test;
test.reverse(a,begin,end);
}

CAsmTest::reverse(unsigned char a[],int begin,int end)
{
//c言語
/*
unsigned char temp;
while(end>begin){
temp=a[begin];
a[begin++]=a[end];
a[end--]=temp;
}
*/
//アセンブラ
__asm{
mov eax ,begin
mov ebx ,end
mov ecx ,ebx
sub ecx ,eax
shr ecx ,1
cmp ebx ,eax
jbe END_FUNC
LOOP_HEAD:
mov esi,eax
mov edi,ebx
mov al,byte ptr [a+esi]
mov bl,byte ptr [a+edi]
mov byte ptr [a+edi],al
mov byte ptr [a+esi],bl
inc eax
dec ebx
loop LOOP_HEAD
END_FUNC:
}
}
なべちゃん@abk  [2001/08/09 Thu 15:19:06]  [202.236.152.84]

CTRL-Z が単純に入ってないだけでは?
昔はいれるのが常識でしたが最近は入れないのが
常識のようですし >CTRL-Z

#まえはエディタが付加してたんですけどねぇ...

.db  [2001/08/09 Thu 07:39:07]  [202.224.108.75]

こんにちは。 .db です。
構造体の扱いが 5.1 と他では異なるようですね。
/Zm オプションの有り無しでも異なりますが、
mov al, [si].a.b とすると解決できました。
ではまた。

マキ志摩  [2001/08/07 Tue 23:34:33]  [143.90.219.46]

テキストファイルの最後にはCtrl-Zが在ると聞き
コマンドプロンプトで、
a.exe < b.txt というように
a.exeにb.txtファイルを渡しました。
そして、ファイル内の文字を1文字ずつ取得していき
Ctrl-Zまでループしました。

ところが、正常に終了せず止まってしまいます。
アスキーの「はじめて読むMASM」のP108の例題をやっており、
「ファイルの終端まで1文字ずつ読みとる」という処理がしたいのですが、Ctrl-Zがテキストファイル中に見つからず、上手くいきません。
Win98SE, MASM6.0と
PC98のDOS3.3cで試しました。が、うまくいかないんです。

assume cs:code,ds:code,es:code,ss:code
code segment

org 0100h
start: mov AH, 08h
int 21h ;文字入力
mov DL, AL

mov AH, 02h
int 21h ;文字出力

cmp DL, 'Z'-'A' + 1 ;^Zとの比較、1Ahと比較しても駄目でした;
jne start

mov AH, 4Ch ;終了
mov AL, 0
int 21h

code ends
end start

.db  [2001/08/06 Mon 15:04:24]  [202.224.108.128]


こんにちは。 .db です。
masm32 を使用して masm5.1 と同様な構造体を定義しました。
コロン演算子を使用すると masm 5.1 では発生しなかった undefined symbol が発生します。

a struct ; struc も同様でした。
b db 0
a ends
mov al, [si].b ; undefined symbol の発生します。

どのようにエラーの回避するのでしょうか ?
google で検索するとコロン演算子を使用できるサンプルも発見したのですが設定の方法なのでしょうか?

よろしくお願いします。



fox  [2001/07/31 Tue 15:31:41]  [211.133.141.4]

お騒がせしました、落ち着いて資料を見返したところ、
なんとか解決しました。
どうもありがとうございます。

原因は滅茶苦茶くだらないことでした。

GDTR struc
 LIMIT db ?
 PTR dd ?
ends

死刑ですね、これは。
人間焦るとロクなことがないですね・・・




e-mail: mist@e-net.or.jp
Structured Anchor Tree Return to Menu Return to Parent Menu 
Powered by Unit Missing Link.