• ベストアンサー

BIOSによる表示

anisolの回答

  • ベストアンサー
  • 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は不要でした。

関連する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」から入力しても同様のコメントが返ってきます。 プログラムを実行するにはどうすればよいでしょうか?