• ベストアンサー

BIOSによる表示

こんばんわ。お世話になります。 今, 自分はフロッピーをさした状態でPCの電源を入れるとそのフロッピーに格納されているプログラムが動くようにしたいと思っています。 その手始めとして, 文字を表示させたいのですが, どうもよくわかりません。 今までに自分は mov ah,0 mov al,03 int 10h で画面設定をし, mov ax,b800 mov es,ax mov di,0 mov byte ptr es:[di],41 mov ax,ff00 int 10h hlt なんてアセンブラを書きましたがwindows付属のdebugではこれはコンパイルできません。コンパイルできたと仮定して, これをrawriteでフロッピーに書き込むつもりです。 現在, 私のもとにある最も簡単なアセンブラはdebugです。nasmもありますが, 不勉強のため 使い方が良くわかりません。 有効なソースをお教えください。よろしくお願いします。

  • funi2
  • お礼率100% (31/31)

質問者が選んだベストアンサー

  • ベストアンサー
  • anisol
  • ベストアンサー率48% (146/301)
回答No.4

funi2さんのユーザ情報を拝見させていただいたところ、かなりコンピュータに詳しい方のようですね。以下の回答は釈迦に説法かもしれませんが、御了承を。 DOS/VのINT 10Hについて私も調べてみました(参考URL1)。funi2さんは擬似テキストバッファへの書き込みを行っていたようですが、そのアドレスが正しく設定されていないことが問題だったようです。AH=FEHでアドレス取得すると正しく表示できます。 ■例1. 0100 MOV AH,00 ;ビデオモード設定 0102 MOV AL,03 ;テキストモード 80×25 0104 INT 10 0106 MOV AX,B800 0109 MOV ES,AX 010B MOV DI,0000 010E MOV AH,FE ;擬似テキストバッファ先頭アドレス取得 0110 INT 10 0112 MOV CX,0001 ;再描画文字数 0115 ES: 0116 MOV BYTE PTR [DI],41 0119 MOV AH,FF ;画面表示の更新 011B INT 10 011D HLT 011E JMP 011D ;念のため(外部割込みなどでHLTから抜けることがあるため) 文字列の表示はAH=1301Hでできます。 ■例2. 0100 MOV AH,00 0102 MOV AL,03 0104 INT 10 0106 MOV DL,00 ;書き込む桁位置 0108 MOV DH,00 ;書き込む行位置 010A MOV BL,07 ;属性 背景黒、文字灰色 010C MOV BH,00 ;ページ番号 010E MOV CX,0008 ;文字数 0111 MOV AX,CS 0113 MOV ES,AX ;ES←CS, ESは文字列のあるセグメント 0115 MOV BP,0120 ;文字列のアドレス、絶対アドレス 0118 MOV AX,1301 ;カーソル移動をともなう文字列表示 011B INT 10 011D HLT 011E JMP 011D 0120 DB 'piyopiyo' ・フロッピーへの書き込みをしなくても、debug上でテスト実行ができます。例2.ではg=100,11dとします(gはgoコマンド)。g=xxxx,yyyyでxxxxは実行開始アドレス、yyyyはブレークポイント(ブレークポイントの命令は実行されない)。 ・debugではラベルが使えないため、アドレス指定は絶対アドレスになることに御注意。またu(unassemble, 逆アセンブル)コマンドが便利です。 ・lighteningさんの御指摘「ブート時にBIOSコールは使えます」ありがとうございます。なおdebugではcomモデルしか書き込めず、exe2binは必要ありません。 ・先の私の回答で、書きこみバイト数の指定をcxだけで行いましたが、bxで書き込みセグメント長が指定されます。bxを0000にすることをお忘れなく。 ・すでにご存知かもしれませんが、"bootable hello world program"として参考URL2のソースコードが参考になります、アセンブラの表記がdebugと異なることに注意してください。 実は私のパソコンは情けないことにフロッピードライブがないため、ブート時の実験はできません。すみません。 参考URL1. DOS/V INT 10h 私的 REFERENCE http://hp.vector.co.jp/authors/VA003720/lpproj/int10h/int10h.htm 参考URL2. Unios http://www.netspace.net.au/~gok/resources/

参考URL:
http://hp.vector.co.jp/authors/VA003720/lpproj/int10h/int10h.htm, http://www.netspace.net.au/~gok/resources/
funi2
質問者

お礼

すっ, すごい...回答ありがとうございます!! こんなに調べていただいて...本来私がやらねばならぬことなのに(感激涙)。 で, 本当は実行してどうで, ってことをお礼に書くはずだったんですが, さまざまな事情により, また明日になります。本当は書きたくないのですが, のちにこのページを見てチャレンジしようという方がいるときの為に。 上のコードをdebugに入れ, 実行すると, まずwindowsでなくなります。本当は裏でwindowsが走っているのでしょうが, 画面が切り替わり, パニックに陥り, 電源強制カット(Ctrl-CとかCTL+Alt+delがおそらく正しいのだろう)。もちろん再起動すると, 異常終了のため, ディスクスキャンがかかります。おまけに理由不明でTAが使えなくなる始末。回答や実験が遅れてたのはこのためです。TAは一回電源を切って, windowsも再起動したら復活しました。 ここで強調しておきたいのですが, anisol様を責めているのではありません。アセンブラを扱いながらこういうところに気がつかなかった私が悪いのです。アセンブラは最もコンピュータに近い言語ですからこういうことは当然起こることですよね。linusがあやまってminixのパーティションを壊したというのが良くわかりました。 最後に。debugに入れるときに, 私がとある行を抜かしたとかそういうこともよくある話。慎重にやりたいと思います。なお, この実験の報告は補足にて行いたいと思います。 ご指南ありがとうございます!!

funi2
質問者

補足

昨日は即結果を出せず申し訳ありません。改めて, 本日実験してみました。 例1に関しては完璧です。まさに私が欲しかったソースとなっています。 例2に関してはpiyopiyoが化けています。なぜかはこれから解析しようと 思っています。 なお, ソースの下にあることについてですが, debug上のテストは私はwindows Meでやっているのですが, ことごとく, 良くない状態に入るので, Meを使っている人は注意がいるかもしれませんね。 次に確かにdebugでつくったcomをrawriteでフロッピーに書き込めば, そのまま期待通りの動きをするので, debugの場合, exe2binは不要でした。

その他の回答 (9)

  • anisol
  • ベストアンサー率48% (146/301)
回答No.10

こんにちは。 alfeimさんの御指摘「Windows 9xではカーネルのメモリ保護機能が働かない」にはびっくりしました。これではOSとは言えないような気が…。Windowsが馬鹿にされる理由がよくわかりました。また、割込み禁止して無限ループに入れるとWindows 98は固まってしまうことが判明。もうちょっとタフと思っていたのですが…。いろいろ勉強になりました。 piyopiyoの文字化けの件、お騒がせしました。アドレスの問題をすっかり忘れていました。comモデルでは0100番地からプログラムが配置され、0000~00FF番地まではMS-DOSの作業領域(PSP, Program Segment Prefix)として使われます。 ところで、ちょっと気になったのはdebugで最初にCSレジスタを07B0に設定していることです。こうするとa100で07B0:0100番地から書き込みされることになります。DOS窓では問題ないかもしれませんが、MS-DOSではここはMS-DOSのシステムが置かれている可能性があり、書き込み中に暴走する恐れがあります。debugを起動したときに設定されるCSが空きメモリを示しているので、CSは変更する必要はないです。comファイルは書き込んだプログラムのセグメントの情報は入っていません。 BXは書き込みセグメント長を指定します。つまり BX*10H+CX が書き込むバイト数になります。debug起動時にはBX=0000となっていますが、gコマンドで何か実行した場合、BXレジスタが変更される可能性があるため、設定しなおす必要があります。なお、rコマンドで表示・変更されるレジスタはもちろん現在のCPUのレジスタではなく、gコマンドでプログラムを実行するときに代入されるものです。もうひとつ、CXはCS:0100からの書き込みバイト数なので、例えば012B番地まで書き込みたいときはCXを002BとすればOKです。 それでは、アセンブラの世界を充分に楽しんでください。また何かありましたら質問してください。(とは言っても、自分もアセンブラ/プログラミング初心者で、まともなプログラムを書いたことはないのですが…)

funi2
質問者

お礼

回答ありがとうございます。 お礼遅くなってすみません。 anisol様の言うとおり, windowsのカーネルってそんなもんなんだなぁ。って気がしました。はやいとこ, linux, FreeBSDが使いやすくなって欲しいものです(達人達に言わせれば, 十分使いやすくなったんでしょうが)。 さて, 本題です。csレジスタの扱いは危ないようなので, 今後やめます。いや, なんでcsを変更したかというと, どうしても0000:7c00から始めたかったからです。 でもcsをそうしない方法を考えていて, こないだのソースをみたら, bpに07b0って自分で書いているんですよね。もしやと思い, 最初の4行を消して実験したらできました。間違った知識を身に付けるところでした。 BXの説明ありがとうございます。今後の参考にさせていただきます。 アセンブラの世界に首をつっこんだらなかなか大変でしたが, いろいろなものも見えてきました。 ありがとうございました。例により, 23日AM00:00まで, 一応開けておきたいと思います。 それではもう一度。ありがとうございました!!

  • alfeim
  • ベストアンサー率58% (114/195)
回答No.9

や、別にVMWareでもいいんですけど、この前新しいVerの紹介見てたらどうもWindows9x/Meを土台に動くVerが見つからなかったので・・・ たしか以前のVerではあったとおもったのですが・・・ あ。名前にだまされた(笑) VMware for Windows NT and Windows 2000 なんて名前だからてっきりHostOSがこれだけかと思ってしまった(^^; 昔は9xにも対応してたはずなのにと思ったんですが(^^; LinuxではVMWare Expressがありますね。 こっちの方が安いようです。動作速度はどれくらいなのか見た事無いので知らないですが・・・Windows版の方は知り合いがCeleron 300(Aでない方)に目盛り256MBで使っていたのを見た事がありますが、結構な速度で動いていました。フルスクリーンにすればPen100程度の速度ぐらいはあったようです。 #新VerではDirectXのサポートはどうなっているんだろう? >リアルタイムOS fnui2さんのおっしゃってるのは「プリエンプティブマルチタスク」の事ではないでしょうか? プリエンプティブマルチタスクではタイマを利用して実行プロセスを切り替えます。たとえプロセスが暴走していようが、while(1);であろうと関係ありません。 それに対してノンプリエンプティブマルチタスクではタイマによる切り替えではなく、各プロセスが自発的に制御をOSに返すまで実行権を握る事が出来ます。ようするに一つのプロセスが暴走すればOSが固まってしまうOSがそうです(ex. Windows 3.x、MacOS 9など) それに対してリアルタイムOSというのは一部のイベント(だいたいは割り込みですね)に対して「一定時間以内に処理を完了し実行権をOSに返す」事が出来るOSです。たとえば工業機械のロボットのように暴走した場合、人命に関わるような装置の場合、強制停止ボタンがついてるのが普通ですが、これがリアルタイムOSでなかった場合、強制停止ボタンを押しても「OSがビジーです・・・(略)」とか言って装置が止まらなかった場合、とんでもない事になる事はわかりますよね? 当然こういう場合、装置は決められた時間内に停止する事が求められるわけで、こういう分野でリアルタイムOSが利用されます。 また、これらのOSはほとんどが一つのOSにしめられています。 それはTRONの工業規格版であるiTRONと呼ばれる製品が利用されており、我々の廻りにあるほとんどの工業製品でOSが必要なものはこれで動いているはずです。 >Xが起動しない それはご愁傷様です(^^; うちのビデオカードもマイナー所(3DLabs Oxygen VX1)なので以前BeOS試したら見事にモノクロ画面でした(^^; Xを使いたい、というだけであればWindows下でも動きますよ >いや, 本当はlinuxとかFreeBSD使いたいんですよ。 私の場合、UNIX系のCUIシステムは利用したいが、GNOMEは重いので嫌(笑)、という結果、Cygwin環境によってほとんどUNIX on Windowsな環境になってしまいました(笑)(上記URL参照)。

funi2
質問者

お礼

回答ありがとうございます。 VMware... 結構重いとか聞きましたけど, そうですか。結構快適にうごきますか。でもメモリが256M... すごいですね。自分のはノートPCで限界が128Mなんで無理です。ちょっとくやしい。 リアルタイムOS... 知ったかぶりをしてしまった!! お恥ずかしい。勉強になりました。正しい知識を身に付けるようにします。 X... 昔, 私もwindows上でチャレンジしましたが, 320x200の画面にしかならず, 苦労したので, そのプロジェクトはそこでやめました。なんか不安定になったような気も。 cygwin... 私も使ってます。これのbashがないと, 今はいろいろつらいですね。telnetとかもcygwinの使うし。 今一度, 回答ありがとうございました。さて, 大分出尽くしたようなので, ここでこの質問を締め切りたいと思います。一応, 19日AM00:00まで開けておきますが, それで何もなければ, 閉めたいと思います。 皆様, いい勉強になりました。ありがとうございました!!

  • alfeim
  • ベストアンサー率58% (114/195)
回答No.8

>暴走することはあってもほかのwindowsのプロセスに影響を与えることはない。 >DOS窓のプロセスをkillして, 再起動すれば元のように使えるようになる。 についてですが9x(Me)ではユーザアプリケーション同士のメモリ保護は働きます が、kernelのメモリ保護機能が無いため、暴走時にkernel空間のメモリを書き換えると暴走する可能性があります(このへんはNT/2000/Xpではちゃんと保護されている)。 というわけなんで、不味いときにはやっぱり固まります(^^; (NT系でもリアルタイムOSではないのでユーザプロセスのプライオリティを高くして無限ループに突っ込ませれば固まってしまいますが・・・) >DB 'a'とDB 41を比較してみたのですが, DB 'a'は61と書き込まれています。 >DB 41はもちろん41と書き込まれています。No.4では41で見事にAと表示された あってますよ? 小文字の'a'は0x61ですし大文字の'A'は0x41です(ASCIIコード時) OS内からちゃんと表示できて、ブートローダから出来ないって事は初期化部分が不味いような気がします。手元にATに関する資料が無いのではっきりとした事が言えないですが・・・ >P.S. テスト用のマシンが欲しい...いちいちリブートするのは飽きた... Virtual PC for Windowsなどの仮想AT互換機を用意してみるというのはどうでしょう?ちとお値段が張りますが(199ドル)ブートシステムから動作するので、ブートローダの実験も出来るはずです。これなら暴走しても仮想マシン内だけの問題なのでアプリケーションを終了させれば(理論上は)OSに問題はないはずです。

参考URL:
http://www.zdnet.co.jp/news/0107/02/virtualpc.html
funi2
質問者

お礼

回答ありがとうございます。 kernelの保護機能... うーん。確かにDOS窓で, 実験して固まるとmule for winまで壊したもんなぁ。 NT系と9x系の違いって完全32bitかそうじゃないかだけと思っていました。 kernelというとFreeBSDとかlinuxのカーネルはリアルタイムOS(プロセス自身が CPUに制御を戻すのではなく, カーネルがプロセスの制御を管理しているという 感じで使っておりますが)ですよね。 DB 'a'... すみません。昨日お礼を書いているときにあっ, そうかぐらいの 勢いで実験したんで, 大文字と小文字の違いを忘れてました。ご迷惑を おかけしました。 Virtual PC for Windows... VMwareはどうでしょう。私のwinMeはくさり きっているようなので(笑)。いや, 本当はlinuxとかFreeBSD使いたいんですよ。 画面の感じがしっくりくるのがwindowsなのと, 私のS○TECはXが起動 しないんですよ。 すみません。ぐちっぽくなって。 いい勉強になりました!!

  • anisol
  • ベストアンサー率48% (146/301)
回答No.7

CLI, HLTなどに関してはalfeimさんのおっしゃる通りだと思います。私の書き方が悪かったです。CLIについては昔のWindows(Windows 3.1?)では実行スピードを上げるため、あえて本当に割り込みが禁止されるという話を本で読んだことがあったので、あのような書き方をしました。HLTに関しては、Windows 98では「親切にも」一般保護例外のメッセージを出してくれる、というふうに書くべきでした。Windows 2000のDOS窓では単純にHLT命令は無視されるだけに対して、Windows 98ではCLIの後のHLTの時だけ一般保護例外で警告してくれることが親切(おせっかい?)に感じたもので。 また、funi2さんに誤解を与えたかもしれませんが、Windowsが暴走に強いというのは「DOS窓の中で暴走してもWindowsの機能自体には影響しない」という意味です。例えば無限ループをDOS窓で実行すると(先のプログラムのHLT, JMP 011Dのように)Ctrl+Alt+Delの強制終了でしか終了できませんが、他のプログラムには何も影響ないはずです。再度DOS窓を立ち上げてdebugを実行してもかまわないと思います。先ほどもめちゃくちゃなINTを実行したり、I/Oポートにでたらめな数値を書き込んだりしてみましたが、Windowsの機能には何も異常がなく、今メモ帳を使っています(ただし昔のWindowsとPC-9821の組み合わせではマウスの動きが変になったりする影響があった)。 ですからDOS窓のdebugで暴走した場合、強制終了を掛ければすぐにまた作業のやり直しができるので、簡単なプログラム(せいぜいBIOSコールを使う程度でI/Oポートはいじらない)ならWindowsのほうがデバッグしやすいと思うのですが…。ただし、Windows Meは特別ヤワなのかもしれません。 ハードに直接アクセスするような場合は、alfeimさんのおっしゃる通り、MS-DOSを使ったほうがやりやすいと思います。まあアセンブラはハードを直接いじれることが醍醐味のひとつでもあるので、Windowsの管理下のアセンブラは面白くない、とも言えるかもしれませんね。暴走もアセンブラの魅力です? (追伸 piyopiyoの文字化けは解決されたでしょうか?心配です)

funi2
質問者

お礼

回答ありがとうございます。 先のalefiem様の回答とあわせて私が理解するところに, いわゆるDOS窓でアセンブラプログラムは実行可能だが, その実行には 常にVMMとかVPICの仲介役が入り, 100%のマシンアクセスは不可能である (例えばHLT)。しかし, そういった機構のおかげで, DOS窓のなかで 暴走することはあってもほかのwindowsのプロセスに影響を与えることはない。 DOS窓のプロセスをkillして, 再起動すれば元のように使えるようになる。 ってことですね。 さて, piyopiyoの文字化けですが, そのDOS窓でのpiyopiyo.comの実行は anisol様の期待通りにpiyopiyoとでてきます。しかし, これをフロッピーに 書き込みリブートして実行すると, やはり文字化けするしだいです。 すみません。実はAが表示された後, 満足のあまり, ほかの勉強したり, 風邪引いたりしてました。従って, 実はあの後, ほとんど進んでない状態です。 でもalfeim様やanisol様の話を考慮すると, どうやら自分のハードウェアが悪い のではとか考え始めてます。というのは,今思いついて,DB 'a'とDB 41を 比較してみたのですが, DB 'a'は61と書き込まれています。 DB 41はもちろん41と書き込まれています。No.4では41で見事にAと表示されたので,そういう違いかと思っています。ハードウェアが悪いって言うかコード体系が 違うんですね。きっと。で,何で実験しないかというと,眠いからです。 すみません。まだちょっと病んでいるんで。明日, また補足に書きたいと思います。すみません。 P.S. anisol様の実験魂には感動しました。なにが起こるかわからないのに, わざわざめちゃくちゃなデータで結果を出してくれるとは!

funi2
質問者

補足

こんばんわ, funi2です。 piyopiyoの文字化け直りました。 どうやらセグメントが悪かったらしいです。 以下にpiyopiyo.dbgをのせます。 rbx 0000 rcs 07b0 a 100 mov ah,00 mov al,13 int 10 mov dl,00 mov dh,00 mov bl,08 mov bh,00 mov cx,0008 xor ax,ax mov es,ax mov bp,0123 add bp,7b00 mov ax,1301 int 10 jmp 011d DB 'piyopiyo' rcx 012b n piyopiyo.com w q 自分でもいまだにrbxに何の意味があるのかはわかりません。 で, rcsですが, いわゆるブートローダは0000:7c00から始めるようです。 (とあるプログラムをみたらそうなっていたんで) とにかく, piyopiyoの文字化けは直りました。 ご心配おかけしました。No4.1のときはVRAMに書き込んでいたので, こういうことはなかったんですね。

  • alfeim
  • ベストアンサー率58% (114/195)
回答No.6

直接そのプログラムとは関係ないのですが、Windows下でAssemblerを組む上での注意を・・・ Windows9x(Me含む)ではVxDのVMM(VirtualMachineManager)とVPIC(VirtualProgramableController)が動いており、マシンネイティブなリソースに直接アクセスする事はまず不可能です。 だいたいのアクセスにおいてVMMかVPICの仲介が入ります(VMMは仮想86マシンの管理、VPICは仮想割り込みコントローラです)。この仲介があるため、CLI命令はVPICにトラップされ、その命令を発行した仮想マシン内のみで無効になっていると思われます(それ以前にCPUがユーザモードで走っているでしょうから、単に無効命令としてトラップされているだけかもしれません)。 また、anisonさんがおっしゃったHLT命令は特権命令なのでユーザモードでは例外トラップされて実行できないはずです(そのため一般保護違反が発生する)。 このような理由があるため、上記質問のようなプログラムのテストはWindows下ではまともにテストできないとおもっておいた方がよいかとおもいます。なのでできればMS-DOSやPC-DOSのようなマシンリソースに直接アクセスできるOS(あれをOSと呼ぶのに抵抗がある人もいるでしょうけど(^^;)を利用する事をオススメします。MS(PC)-DOSかであればExtenderや仮想86モードを利用したプログラムが無い限り、マシンリソースに直接アクセスできますので。

funi2
質問者

お礼

回答ありがとうございます。 windows9xでは, テストすら出来ませんか... 私も暴走がいやで, windows上でテストすることは放棄しましたが。 暴走する理由がはっきりしてよかったです。ありがとうございます。 P.S. テスト用のマシンが欲しい...いちいちリブートするのは飽きた...

  • anisol
  • ベストアンサー率48% (146/301)
回答No.5

暴走ですか…。大変でしたね。MS-DOSの時代は、アセンブラプログラムの暴走でリセットをかけることなどはいつものことでしたが、Windowsはかなり丈夫なので注意喚起することをすっかり忘れていました。 (例えばCLI(割り込み禁止)はWindows上のDOS窓では無視され、Ctrl+Alt+Delのキーボード割り込みは利いているし、割り込み禁止してからHLT命令をかけると一般保護例外になったり…。Windows98ではそうなるのですが、Windowsの種類によっては暴走に弱いかもしれません。funi2さんのお使いのWindowsは何でしょうか?) 全画面表示になってしまったら、まずAlt+Enterを試してみてください。暴走した場合は普通はCtrl+Cは利きません。Ctrl+Alt+Delを試してみて、利かなかったらやむを得ず電源断です。 プログラムは一応実行できることを確認してから、逆アセンブルしてできたソースファイルを載せたのですが、くれぐれも入力ミスや実行アドレスの間違いには御注意を。u100で逆アセンブルして確認するとよいと思います。 ローダの実行中はWindowsの管理下にないので、暴走したら電源断しか手段がありません。くれぐれも慎重に。うまくいくことを願っています。(本当は私がやってみたいのだが、安物パソコンゆえにフロッピードライブが…)

funi2
質問者

お礼

私はwindows Meを使っているのですが...ただでさえ, Meは挙動不審な動作をするときがあるので, なかなか心が休まりません。 また, No.4のソースではディスプレイのモードを変換しているので, 全画面状態になったように見えたのか, それとも本当にただの全画面状態だったのかはわかりません。 緊急停止手段はいっぱい知っておいたほうがいいですね。 さて, No.4の補足にNo.4のソースの結果を載せました。これはフロッピーに書き込んで, フロッピーブートした結果です。みごとにAの文字が出てきたときは一瞬放心状態になってしまいました。今, 感動がじわじわとこみ上げてきています。anisol様のおかげで, アセンブラに対するかなりの足場が組めたと思います。 本当に感謝しております。 さてさて, 最初の質問に対する完璧といえる回答が得られたので, そろそろこの質問を閉じたいと思います。ほかの発言の機会をとっておくために, とりあえずあと2日間だけ開けておきます。変化がなければ, 13日AM00:00に閉じたいと思います。 回答を下さった皆様ありがとうございました。これからの糧にしていきたいと思います。 もっとも有効な回答を下さったanisol様, ここに今一度感謝を記します。 No.5の訓示を心に置き, アセンブラの道をしばらく歩んでいきます。 ありがとうございました!!

  • igmp
  • ベストアンサー率28% (156/546)
回答No.3

No.1である程度解決しているようですし、既にご存知かとは思いますが 参考程度に一言。 DOS/V(IBM系)パソコンのBIOSコールでは、"int 10h"はVideo(表示関連)で、 "int 13h"がフロッピー、またはディスクとなっています。

funi2
質問者

お礼

回答ありがとうございます。 いや, アイデアを実現する道具がそろってから実にまだ数日しかたっておらず, 全然手探りの状態です。はっきり言ってこの世界ではひよっこ同然です。 ですからこういうちょっとしたアイデアというのも大変勉強になります。 どうせいずれは, ディスプレイに書き込めてなぜ, フロッピーに書き込めないんだぁ!!と叫ぶ日がくるでしょう(果たしてほんとうにそうか!?)。 そのときに役に立たせていただきます。 ありがとうございました!!

回答No.2

「IBM PC & DOS/V 活用ハンドブック」(CQ出版社)という本にブートストラップローダのサンプルが載っています。 かなり古い本なので手に入るかどうか分かりませんが。 補足としては  ・COMモデルの形式で作成、EXE2BINを通さないといけないようです。  ・ブート時にBIOSコールは使えます。 それにしても懐かしい話題で私も感激です。

funi2
質問者

お礼

回答ありがとうございます!! こういう参考書紹介も大歓迎です! そうかブートストラップローダというものを見ればいいのかということで, この時間...図書館に行くわけにも行かないので, google。 するとありました。が, (今の私には)巨大でしばらくかかりそう。しかし, これは参考になります。ありがとうございます! 頑張って解読を進めていきたいと思います。ありがとうございました!

  • anisol
  • ベストアンサー率48% (146/301)
回答No.1

今時アセンブラに興味を持ってくれる人がいるなんて、私はうれしい、ほんとに感激です。 このプログラムはdebugでアセンブルはできるはずですよ。debugで a と入力し、次のように打ち込んでみてください。 mov ah,0 mov al,03 int 10 mov ax,b800 mov es,ax mov di,0 es: mov byte ptr[di],41 mov ax,ff00 int 10 hlt debugでは数値は暗黙のうちに16進数です。また es: などのセグメントオーバーライドは分けて入力します。入力し終わったら、rcxでレジスタcxを変更して100(書き込みバイト数256byte)にし、nfilename.com(nはnameコマンド)とファイル名を入力した後、wで書きこんでください。DOSモードでfilenameが実行できたらしめたものですが。 でも、これをフロッピーのブート領域に書きこんでも実行できるかどうか…。BIOSは起動後、フロッピーのブート領域(多分0トラックの第1セクタ)から「ローダ」(loader)というプログラムをまず読み込みます。ローダはコンピュータの初期設定などを行い、MS-DOSのプログラムを読み込んでメモリに割り振った後、MS-DOSに実行を移します。これで初めてMS-DOSのシステムコールやBIOSコールがまともに使える状態になるので、必要な準備が整っていないローダの段階でBIOSコールがうまく使えるかはわかりません。 また、悲しいかな私はPC-9801のハード、BIOSの知識しかありません。int 10はDOS/Vパソコンでどんな意味を持つのか知らないので、このプログラムが正しいかわかりません、ごめんなさい。できるだけ助力はしたいのですが…。

funi2
質問者

お礼

回答ありがとうございます。それもこんな早い時間に...うぅ(嬉涙) それもdebugの使い方まで...ありがとうございます。 早速debugにて上ソースを打ち込みました。そうかこうやって打つのかと思いながら。ちゃんとアセンブルされ, .comファイルができました。それをrawriteでフロッピーに書き込み, 差し込んだまま再起動。 おぉ? なんか一応GCAテキストモードにはなっているようだ(最初の3行)。しかし残念ながらAは表示されず。 というのが結果です。しかし, それは私のソースのせい。アセンブルできたのはあなた様のおかげです。 これからも精進していきます。ありがとうございました!!

関連するQ&A

  • NASMアセンブリの構文でわからない、書式があります。

    いつも、お世話になっております。 小生、只今、WindowsXPSP3上でnasm0.99.6を使いアセンブリ言語を勉強しています。 今回質問させて頂き点を、ピックアップすると以下の構文です。 12行目のmov ax, word [msgBack] 16行目のmov word [es:di], ax 23行目のmov byte [es:edi], 'A' 50行目times 510 - ($ - $$) db 0 そして以下にソースコード全体を記述させて頂きます。 1[org 0] 2[bits 16] 3 jmp 0x07C0:start ; far jmpする。 4 5start: 6 mov ax, cs ; csには0x07C0が入っている 7 mov ds, ax ; dsをcsと同じくする 8 9 mov ax, 0xB800 ; ビデオメモリのセグメントを 10 mov es, ax ; esレジスタに入れる 11 mov di, 0 ; 一番上の頭の部分から書く 12 mov ax, word [msgBack] ; 書く予定のデータの住所を指定する 13 mov cx, 0x7FF ; 画面全体に書くためには 14 ; 0x7FF(10進数 2047)個のWORDが必要 15paint: 16 mov word [es:di], ax ; ビデオメモリに書く 17 add di,2 ; 1つのWORDを書いたので、2を加える 18 dec cx ; 1つのWORDを書いたので、CXの値を1つ引く 19 jnz paint ; CXが0じゃないと、paintにジャンプし、 20 ; 残りを書く 21 22 mov edi, 0 ; 一番上の頭の部分に書く 23 mov byte [es:edi], 'A' ; ビデオメモリに書く 24 inc edi ; 1つのBYTEを書いたので、1を加える 25 mov byte [es:edi], 0x06 ; 背景色を描く 26 inc edi ; 1つのBYTEを書いたので、1加える 27 mov byte [es:edi], 'B' 28 inc edi 29 mov byte [es:edi], 0x06 30 inc edi 31 mov byte [es:edi], 'C' 32 inc edi 33 mov byte [es:edi], 0x06 34 inc edi 35 mov byte [es:edi], '1' 36 inc edi 37 mov byte [es:edi], 0x06 38 inc edi 39 mov byte [es:edi], '2' 40 inc edi 41 mov byte [es:edi], 0x06 42 inc edi 43 mov byte [es:edi], '3' 44 inc edi 45 mov byte [es:edi], 0x06 46 47 jmp $ ; ここで無限ループに入る 48 49msgBack db '.', 0xE7 ; 背景に使う文字 50 51times 510-($-$$) db 0 ; ここから509番地まで0で詰める 52 dw 0xAA55 ; 510番地に0x55を、511番地に0xAAを 53 ; 入れておく 以下、私の憶測でコードの動作を記述させて頂きます。 12行目のmov ax, word [msgBack] ・axレジスタに、wordで表された、msgBackのアドレスを格納している。 16行目のmov word [es:di], ax ・wordのデータになる、es:di(esに対して、diがオフセットアドレスと見て)、axのデータを格納している。 23行目のmov byte [es:edi], 'A' ・byteのデータになる、es:ediに対して、'A'と言う値を格納している。 50行目times 510 - ($ - $$) db 0 ・これに関しては全くわかりません。$がそのそもよくわかりません。 お忙しい中、誠に恐縮ではありますが、以上をご確認して頂き、 先輩方、ご教示宜しくお願い致します。

  • コマンドプロンプトのデバッガ

    以下のように,コマンドプロンプトのDEBUGコマンドでアセンブリ言語を書いたのですが,COMファイルとして保存する方法(http://wisdom.sakura.ne.jp/programming/asm/assembly29.html)が分かりません。お願いします! debug a 100 mov ah,a mov dx,9100 mov byte ptr[9100],20 int 21 ret a 200 sub bl,30 ret a 300 mov bl,byte ptr[9103] cmp bl,2b je 318 cmp bl,2d je 31a cmp bl,2a je 31a cmp bl,2f je 31a add al,dl ret a 400 mov ah,0 mov dl,a div dl mov byte ptr[9200],0d mov byte ptr[9201],0a add al,30 mov byte ptr[9202],al add ah,30 mov byte ptr[9203],ah mov byte ptr[9204],24 mov ah,9 mov dx,9200 int 21 ret a 9000 call 100 mov bl,byte ptr[9102] call 200 mov al,bl mov bl,byte ptr[9104] call 200 mov dl,bl call 300 call 400 mov ah,4c mov al,0 int 21 g =9000 9021

  • NASM(独習アセンブラのサンプルソース)について

    独習アセンブラ初版5刷のサンプルソース(リスト6.7、102p)での疑問です 下の方にあるコメントアウトしているputc関数って何のためにあるんですか? どこからも呼び出してないのでいらないと思うのですが… アセンブラはNASMです ※本に書かれてるソースはコメントアウトしてません、コメントアウトしてもアセンブルできました bits 16 org 100h mov dx,sfile mov al,0 mov ah,3dh int 21h jc endquit mov [ifh],ax mov dx,dfile mov cx,0 mov ah,3ch int 21h jc endquit mov [ofh],ax readb: mov bx,[ifh] mov dx,buf mov cx,1 mov ah,3fh int 21h test cx,ax jz endquit jc endquit mov bx,[ofh] mov dx,buf mov cx,1 mov ah,40h int 21h jmp readb endquit: mov bx,[ifh] mov ah,3eh int 21h mov bx,[ofh] mov ah,3eh int 21h mov ax,4c00h int 21h ;putc: ; push ax ; mov ah,2h ; int 21h ; pop ax ; ret ifh dw 0 ofh dw 0 sfile db "srcfile.txt",0 dfile db "destfile.txt",0 buf resb 2 私が思うにリスト6.6(100p)のreadbラベルのところでこれを呼び出してるのでソースを流用して消し忘れてるだけなんでしょうか?

  • NASMアセンブリのセクションについてご教示ください。

    NASMアセンブリのセクションについてご教示ください。 いつもお世話になっております。 前回も大変勉強になるご教示頂き誠に、感謝申し上げます。 小生、只今WinXPSP3上でNASM0.99.06を使用し、アセンブリ言語を勉強しています。 今回質問させて頂きたいのはNASMによる、セクションです。 NASMでは.text, .bss, .dataセクションがありますが、 例えば下記のアセンブリソースの、 一番最初に記述する[org 0]なども広義の意味でのセクションに該当するのでしょうか? ソースは以下の様になっております。 -----source.asm----- [org 0] [bits 16] jmp 0x07C0:start start: mov ax, cs mov ds, ax mov ax, 0xB800 mov es, ax mov di, 0 mov ax, word [msgBack] mov cx, 0x7FF paint: mov word [es:di], ax add di, 2 dec cx jnz paint mov edi, 0 mov byte [es:edi], 'A' inc edi mov byte [es:edi], 0x06 inc edi mov byte [es:edi], 'B' inc edi mov byte [es:edi], 0x06 inc edi mov byte [es:edi], 'C' inc edi mov byte [es:edi], 0x06 inc edi mov byte [es:edi], '1' inc edi mov byte [es:edi], 0x06 inc edi mov byte [es:edi], '2' inc edi mov byte [es:edi], 0x06 inc edi mov byte [es:edi], '3' inc edi mov byte [es:edi], 0x06 jmp $ msgBack db '.', 0xE7 times 510-($-$$) db 0 dw 0xAA55 -------------------------- 以上です。 最後から2行目の箇所に$$の特殊シンボルが使われており、 私としてはセクション(.textセクション等)が記述されていないのに、 $$はどこのセクションを示しているのかが分かりません。 そこで、書籍などで調べてみたところ、セクションとはそのコードがどこに置かれるかを決めるもので、 上記に記述させて頂いたコードだと、[org 0]がある為、 このコードは0000 0000に配置される事になり、 $$は0000 0000を指し示すものだと思っています。 この解釈で間違っていないでしょうか? お忙しい中、大変申し訳ございませんが、先輩方ご教示宜しくお願い致します。

  • 自分でアセンブラ言語を作れる?

    自分でアセンブラ言語を作れる? あるCPUにmov命令というのがありますが命令名をソフトウェアレベルで変えることは 出来るのでしょうか? (mov ax,1をmove ax,1にしたり) アセンブラはCPUが同じならどれも同じだと思っていたのですが プログラムを終了する時、windowsはint 21hなのにlinuxはint 0x80なので 疑問に思いました。

  • shift_jisの文字コードを出力させるには

    圧縮・解凍プログラムを作ろうと考えた時、大量の文字が必要であることに気づき、 Shift_Jisの全角文字を利用してみようとおもいました。でも、どうやって利用するかがわからず、 とりあえず16進数で8940hである院という文字をNASMアセンブラで1文字出力してみることにしました。 org 100H section .text start: mov ax, 0200H mov edx, 8940H int 21H mov ah, 4CH int 21H これでコンパイルはできたものの、実行すると変な処理をしていました。 そこで疑問に思ったことは、 なぜDLレジスタにASCII文字コード入れるとその文字が出力されるのか、ASCIIコード自体はそれに対応する文字を格納するアドレスではないはずなのに。 結局どうすればShift_jis全角文字がつかえのか?と。 申し訳ありませんがよろしくおねがいします。 それと、たくさん文字がつかえるコード(規格といった言い方で正しいのでしょうか?)の情報をもらえたらうれしいです。

  • アセンブリ言語で。

    下のようなソースをアセンブルすると 6:error: parser: instruction expected という、エラーが出ます。 mov ah,2 mov dl,DATA int 21h mov ax,4c00h int 21h DATA byte 'A' 6行目に問題があるようなので下のように書き直したらきちんと動作しました。どうして、上のような記述ではうまくいかないのでしょうか?? mov ah,2 mov dl,'A' int 21h mov ax,4c00h int 21h 環境はwindowsXPでnasmとalinkを使っています。 nasmw test.asm -fobj alink test.obj -oEXEとしてアセンブルしました。 わかる方お願いいたします。

  • アセンブラ、ビデオモード al 13h でマウスのポインタを表示

    mov ah, 0 mov al, 13h int 10h のモードでマウスのポインタを表示することは可能でしょうか? 以下のコードを書いてみまして、ビデオモードを設定しない場合は Alt + Enter でフルスクリーンにすればポインタが表示されます。 環境は masm32、interrupt のリストはこちらです ↓ http://www.ctyme.com/intr/int.htm ---------------------------------- .model small .stack 100h .data .code start: mov ax, @data mov ds, ax mov ah, 0 ; set video mode mov al, 13h int 10h ; mov ax, 0 ; reset ; int 33h ; mov ax, 20h ; int 33h mov ax, 1 ; show mouse pointer int 33h mov ah, 1 ; wait for key int 21h mov ah, 0 ; restore video mode mov al, 3h int 10h mov ax, 4c00h ; exit int 21h end start

  • 8086アセンブラで、メモリ間のデータをストリング命令でブロック転送したい

    ソースが長めなので、簡潔に書きます。ご無礼の段、ご容赦ください。 【目的】PC-9801本体のCバス(汎用拡張スロット)に挿したサウンドボード上の ROM BIOSを読み出し、バイナリファイルに落としたい。既にエミュレータ用に実機からの 吸出しツールは存在するが、ソースが無いので、自作することにした。 その前段階としてアセンブラの修行も兼ねて、ROM BIOSの先頭3ワード(6バイト)を メモリ上のバッファにコピーし、比較して値の合致を確認したい。 将来的にはSCSI ROM BIOSの解析等を試みたい。 【方針】8086のストリング命令でダイレクトにメモリtoメモリでブロック転送を する。具体的にはrep movsbを用い、6バイトを転送する。 【備考】PC-9801-26K互換音源のROM BIOS(少なくとも先頭8バイト)は一意であり、 その並びは、0001h, 0000h, 00d2h である。例外はありません。 86音源でも同様で、下位互換性があることは、拙作ツール(OPNCHK.COM)にて確認済み。 なお、上記バイト列は、セグメントCC000h:オフセット2E00hから読み出し 可能である。 なお実行にあたり、所謂メモリマネージャの類(MELEMM.386等)は一切 組み込まない状態で行なう(EMSメモリマネージャ等との同居対応は将来の課題とします)。 【開発環境】PC-9801DA2(Cyrix Cx486DLC-25MHzに載せ換え; 13.6MB RAM; HA-55BS4 SCSIボード + 240MB SCSI HDD + SONY CPD-17SF9 CRT + NASM 2.06rc10 on NEC DOS 5.0A-H + Turbo Debugger v3.2 と、 秋葉で買ったジャンクFDに入ってたMASM ver 3.00; 予備機 VX41/RS21/EPSON 286VF/EPSON 486HX2/Xv13R16[K6-2 400MHz]/ AT互換機上のNekoIIエミュ/Cygwin上のnasmw.exe) 【参考書】PC-98、8086アセンブラ、テクニカルデータ、古雑誌等 定番本100冊ほど 【拙作コードの失敗点をご指南いただきたい。NASMコードですが、MASM/TASMでも構いません】 ; PC-9801-26K compatible Sound ROM BIOS Copy Program (i/o address 0188h) ; Programmed by OrzHacker666 ; Date 2009-07-13 for NASM 2.06rc10 [Bits 16] org 100h ; COM program section .text start: push es ; これを保存しないと、 push ds ; 画面がめちゃくちゃになる mov ax, 0cc00h ; Sound ROM セグメントアドレス mov es, ax mov ds, ax ; DS:SI -> ES:DI 無意味か? mov bx, 2e00h ; Sound ROM オフセットアドレス lea si, [es:bx] ; ES:BX がSound ROMの開始点 lea di, [ds:sbuff] ; sbuffは仮に確保したバッファ。 ; どこにあるかは、当たり前ですが、不明。そこら辺はCの変数宣言と同じですが。 mov cx, 8 ; とりあえず、アタマ8バイトをコピー cld rep movsb CompareWithOriginal: cmp word [es:bx+4], 00d2h ; これは通る。当たり前。 jne FailedCpyRom cmp word [ds:sbuff+4], 00d2h ; ここで失敗判定。なぜ? jne FailedCpyRom ; sbuffにes:bx~が正しく ; 転送されていないのか? SuccessCpyRom: ; これを拝めれば…。 pop ds pop es mov ah, 9 lea dx, [SUCCESSMsg] int 21h mov ax, 4c00h int 21h FailedCpyRom: ; 見飽きましたOrz pop ds pop es mov ah, 9 lea dx, [FAILEDMsg] int 21h mov ax, 4c00h int 21h section .data SUCCESSMsg: db 'Succeeded !!', 0dh, 0ah, '$' FAILEDMsg: db 'Failed(--;)', 0dh, 0ah, '$' section .bss sbuff: resb 8 ; Cで書くと、差し詰め unsigned char sbuff[8]; であろうか…。 識者の方、よろしくお願いいたします。気になって夜も眠れません。

  • アセンブラを実行したいのですが

    パソコン初心者です。 Windows XPにアセンブラ「NASM」をダウンロードしました。 コマンドプロンプトで簡単なプログラムを実行しようと思います。 以下がプログラムです。 ; dispchar.asm mov ah,02 mov dl,31h int 21h mov ah,4ch mov al,0 int 21h コマンドプロンプトに「; dispchar.asm」と入力すると、内部コマンド、外部コマンドまたは操作可能なファイル、バッチファイルとして認識されていません」と出ます。 同様に、「mov ah,02」から入力しても同様のコメントが返ってきます。 プログラムを実行するにはどうすればよいでしょうか?

専門家に質問してみよう