• ベストアンサー

BIOSによる表示

anisolの回答

  • 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まで, 一応開けておきたいと思います。 それではもう一度。ありがとうございました!!

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