• ベストアンサー

システムコールを使わずに画面に文字を表示する方法

アセンブリの本を読むと、画面に文字を表示する際にはシステムコールを利用しています。 通常はシステムコールを利用すれば問題ないのですが、ブラックボックス的に使うのが嫌なので、一度は内部の動作を理解したいと考えています。 システムコールを使わずに画面に表示するにはアセンブリでどう記述したらよいのでしょうか? または、システムコールではどのような処理をしているのでしょうか? ディスプレイのデバイスドライバが関わっていると思うのですが、そうであるなら、デバイスドライバではどのような処理がされているのか知りたいのです。 OS、処理系はなんでも構いません。 この本を読めばいいよ、という情報でも構いませんのでご教示ください。

  • string
  • お礼率92% (168/181)

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

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.6

>ということは、素人が細かい部分まで独学で理解するのは難しいのかも知れませんね。 最近のビデオカードのドライバは、メーカー内のハードに精通した担当者しか書けないみたいですね。まぁ、ハードの詳細仕様が公開されていないので書けって言われても難しいですが。 http://opentechpress.jp/developer/07/09/04/0117255.shtml Linux系オープンソースでチャレンジは行われているみたいですが、完成したドライバまでたどり着いたプロジェクトは無いようです。 上記ページからたどって、R300の未完成のオープンソースのドライバを見てみましたが、大量のソースコードで読む気もおきません。 興味があったらたどってみてください。

string
質問者

お礼

なるほど。 昔の単純なビデオカードの仕組みを理解する程度で満足することにします。 どうもお世話になりました。

その他の回答 (5)

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.5

まずベーシックなグラフィックVRAMについての説明から。 実際のハードは色々と工夫がしてあって様々な構造をしているのですが、ここは単純な構造と仮定して説明します。 VRAMは、RGBの各色の明るさをドット毎のデータとして持ちます。俗に24ビットカラーと呼ばれるものは、24ビット=3バイトで1つのドットのデータを構成していて、RGBが各1バイトづつの情報を持ちます。1バイトで256段階の明るさを表現し、RGBの明るさの組み合わせで色を表現します。 http://www.hm.h555.net/~irom/g_about/color_01.htm VRAM上には、[R][G][B]を1組として、横x縦のドットサイズ分メモリ上に連続して並んでいます。 [R][G][B][R][G][B][R][G][B]・・・・・・[R][G][B] [R][G][B][R][G][B][R][G][B]・・・・・・[R][G][B] [R][G][B][R][G][B][R][G][B]・・・・・・[R][G][B]  ・  ・  ・ [R][G][B][R][G][B][R][G][B]・・・・・・[R][G][B] ↑こんなイメージです。 CPUからは、RGBの3バイト単位で単なるメモリとして書き換えを行います。 実際のVRAMは、効率の問題から4バイト単位だったり、別の工夫がしてあったりします。 >素人考えではVRAMへ転送する指令は共通にしてしまって、あとはグラフィックカードで適当に処理してくれればドライバが必要ないと思うのですが、それでよろしいでしょうか? その通りです。ハード仕様がすべて厳密に決まっていれば、処理は固定化できてドライバが不要にはなりませんが、様々なバリエーションは不要になります。 ただし、VRAMの初期化や解像度、色数など変更は、細々としたVRAMコントローラのレジスタ設定が必要ですからドライバで吸収してやらないとプログラム側がやることが多すぎます。 本物のPCのビデオカードは、各メーカーが特色出すためや元々厳密にハード仕様が決まっていなかった事から拡張に次ぐ拡張を重ねてきました。逆にハード仕様が厳密に決まっていたら、これほど急激に高性能なビデオカードに発展することは無かったでしょう。 現在のビデオカードは、単にドットを表示するだけではなく様々な機能を搭載しています。 (1)様々な解像度や色数や垂直同期周波数やら細かい設定を切替できる機能。 (2)WindowsAPIのグラフィック系の機能(塗りつぶしやラインを引くなど)をCPUで行わずVRAM側ハードで実現するアクセラレータ機能。 (3)ビデオ再生をサポートするアクセラレータ機能。 (4)3Dに関する3次元の頂点計算やドット単位のエフェクトを行う3Dアクセラレータ機能。 これらは、メーカー毎に独自の実装でメーカー内でもビデオカードのチップのバージョン毎に違っているのが現状です。 本物のドライバの役割。 (1)PCI,AGP,PCI-Xなどの様々なバスで接続されているVRAMへのアクセス方法をプログラム側から隠蔽し同一な方法でのドットデータの転送を可能にします。WindowsPCでは、CPUから見るとVRAMメモリに直接書き込むことはできません。WindowsAPIやDirectXなどを使ってメインRAMからVRAMにドットデータを転送してもらいます。実際の制御はドライバが行います。 (2)グラフィック描画のWindowsAPIを実際のビデオカードの制御コマンドに書き換えて、ビデオカードに指令を出します。 (3)DirectXのバージョンの違いがあっても正しく動くように差分をドライバ側で吸収します。DirectXの様々な機能をビデオカードの制御コマンドに置き換えるのもドライバの役割です。 とハード制御やら、バージョン違い吸収、インターフェイスの単純化など複雑なことをしていますので、ドライバのプログラムは複雑で巨大ですし、ハードウェアの知識なしにソースを理解することはできません。

string
質問者

お礼

週末は出かけていて、お礼が遅くなり申し訳ございません。 ご丁寧なご説明ありがとうございましたm(_ _)m。 大変よくわかりました。 >メーカー毎に独自の実装でメーカー内でもビデオカードのチップのバージョン毎に違っている ということは、素人が細かい部分まで独学で理解するのは難しいのかも知れませんね。

noname#39970
noname#39970
回答No.4

>ディスプレイドライバが担う役割は そのVRAM、昔はマザーボードに一緒になってたのは何となく想像できると思う。 時代が進み拡張で行っているけれど作ってる会社が違うからあべこべな信号指令を出しちゃう事になる。 例えばだけど指令として 0x4f が表示データ転送 というつもりでマザーが発令しても グラフィックボードは 0x4f は特定のメモリを消去する命令かもしれない。 それをとりもつのがドライバ。 そしてマザー側はOSが既定している方法でドライバへ指令を渡す事によって期待通りの仕事をグラボにさせる事ができるようになるという。 なにせドライバって言うくらいだからね。 極端な話、マザー側からはグラボの接続ポートへ対してグラボの命令群や格納データ郡を送れば直接制御できる。

string
質問者

お礼

ご回答ありがとうございます。 つまり、同じ動作をさせたい場合でもメーカーが異なるとグラフィックVRAMへ転送する指令が異なるから、ドライバが必要ということですね。 素人考えではVRAMへ転送する指令は共通にしてしまって、あとはグラフィックカードで適当に処理してくれればドライバが必要ないと思うのですが、それでよろしいでしょうか? 勘違いがあったらすみません。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.3

#1のultraCSさんではないですが私からも説明します。 VRAM(画面)は、RAMという名前が付くとおりCPUから見れば単なるメモリです。テキストVRAMであれば、メモリの特定の場所に文字コードを書き込むと画面に文字が表示されます。画面への表示は、ハードウェアが行いCPU側では特に意識する必要はありません。 これが参考になるかも↓余分なこともかかれてますが(^^ゞ http://members.aol.com/njprog/pakai_24.html MS-DOSからのテキストVRAMの制御は、ここが参考になると思います。 http://www7.plala.or.jp/keny01/asm/dos-ex/index.html フリーで使えるMASMはこちら↓ http://lets-go.hp.infoseek.co.jp/prog02.html >この過程はやはり通常のマシン語で記述されているのでしょうか? >通常のマシン語はCPU内のレジスタとメモリ上のデータのやりとりを記述するものが多いと思うのですが、画面の制御もできるのでしょうか? 別にメモリを操作するだけですので、C言語でも書くことができます。 画面の表示の制御は、画面専用のコントローラ(ハードウェア)が行っています。画面専用のコントローラにパラメータを設定することで解像度や画面モードの切り替えを行うことができますが、これも単なる特定のメモリに値を書き込むことでパラメータを変更することができます。全部自分でやるとなると、その設定も必要になります。 グラフィックVRAMも必要であれば解説しますので、補足してください。

string
質問者

お礼

大変お詳しいご回答ありがとうございました。 リンク先の文章も大変わかりやすかったです。 CPUで行うことはVRAMへの転送までなので、とくにドット1つを青色に光らせるマシン語があるわけではないのですね。 もう少し教えていただきたいのですが、ディスプレイドライバが担う役割はどの辺りでしょうか?

  • ultraCS
  • ベストアンサー率44% (3956/8947)
回答No.2

#1です。手元に解説書がないので、概念的になってしまうし、最近使って折らず、MicrosoftとZilog/Intel/Motorolaのニーモニックが頭の中で混ざっているので間違いを書くかもしれないのはご容赦いただくと言うことで テキストRAMへの転送は通常のMOVなどで絶対アドレスにテキストコードを転送するだけです。 MOV AX,'A' MOV [xxxxh],AX で、xxxxhに'A'が書き込まれ、画面上の該当位置に'A'が表示されることになります。 グラフィックも含め周辺チップの制御は、通常は、チップ上のレジスタに書き込むことで行います。書き込み動作は、CPU側のレジスタに値をセットして、実装されているポートに書き込むことでデータがチップ上に転送されます。 MOV AX,data OUT yyh といった感じです。 なお、AT-BIOSくらいは使った方が良いと思いますね。チップの制御は書き込み時間の遅延や動作遅延を考慮してウェイトを掛ける(NOPのループなど)必要があり、BIOSではそれを考慮しています。 まあ、入り口としては、DEBUG/SYMDEBで直接ニーモニックを打ち込んで、どのように動くか試してみるのが良いでしょう。

string
質問者

お礼

大変よくわかりました。 どうもありがとうございました。

  • ultraCS
  • ベストアンサー率44% (3956/8947)
回答No.1

多分、遼遠な道だと思うので、概念だけ説明しますね。 テキストでよければ、メモリ上のテキストエリアに直接コードを書き込んでしまえば画面には反映されます。ただ、絶対アドレスになるので、CPUがリアルモードでないと難しいかもしれません。バージョンの低いMS-DOSあたりを使い、メモリーマネージャなどは使わないのが簡単かと思います。 アドレスについては、MDA/CGA/EGA/VGAといった画面モードで変わります、知るにはPC-AT(名称は忘れましたが、inside PC-ATのような)のアーキテクチャを解説した書籍が必要です。 テキストVRAMを書き換えれば、あとは、適当なタイミングでリフレッシュされてVRAMに反映され、画面に表示されます。グラフィックも考え方は同様ですが、こちらは更に複雑になります。 なお、現在のグラフィックチップはより高度な命令を高速に実行できるようになっているので、デバイスドライバであっても、複雑な命令を組み合わせて作られており、単純にVRAMを書き換えるような作りにはなっていませんから、デバイスドライバのソースを見ても参考にはならないかもしれません。

string
質問者

お礼

ご回答ありがとうございます。 おかげさまで概念はつかめました。 >テキストVRAMを書き換えれば、あとは、適当なタイミングでリフレッシュされてVRAMに反映され、画面に表示されます この過程はやはり通常のマシン語で記述されているのでしょうか? 通常のマシン語はCPU内のレジスタとメモリ上のデータのやりとりを記述するものが多いと思うのですが、画面の制御もできるのでしょうか?

関連するQ&A

  • システムコールについて。

    アセンブリ言語で、int $0x80はシステムコールと言われていますが、Linuxを知らないとわかりません。システムコールはアプリとカーネルのインターフェースです。 x86 Linux 32bitのシステムコールの呼び出しは int 0x80です。 システムコールはEAXに格納されている数値でいろいろな処理ができます。 https://www.mztn.org/lxasm64/x86_x64_table.html を見ていただくとWRITEのsyscall#は4です。 mov $0x4,%eax でeaxに4を入れているので画面に出力したいのだとわかります。 WRITEの第2引数は画面に出力したい文字列が格納されているアドレスでECXに格納します。 mov %esp,%ecx とスタックポインターのアドレスをecxに入れています。 ESPは push eax でEAXに格納されている$0x616b6157(Waka)がスタックに退避しています。 WRITEの第3引数は文字数です。文字数はEDXに格納します。 mov $0x4,%edx と4が入っているので文字数は4です。 このプログラムを実行させると画面にWakaと表示して元の画面に戻ります。そのためのRETです。 C言語で書けばたった1行。 write(1,"Waka",4) これについて詳しく教えていただけないでしょうか?すみません。

  • 画面の表示がおかしいです

    デスクトップパソコンの画面の表示がおかしくなりました。 電源を入れてすぐ画面全体に点線が入っているような状態です。解像度も640×480になってしまってますし、色もおかしいです。 デバイスマネージャのディスプレイアダプタ「NVIDIA GeForce 8800 GT」に黄色の!マークがでています。 試したこと ・ドライバの再インストール→改善せず ・最新のドライバに更新→改善せず ・システムの復元→改善せず BIOSセットアップの画面は普通に表示されました。 教えてください、よろしくお願いします。

  • システムコール後の振る舞い

    印刷装置の利用の為に、オフィスソフトウェア等のアプリケーションがスーパーバイザーコールを実施した際にも、 OSはデバイスドライバで出力先を認識しているのでしょうか? たとえネットワークプリンタが各PCと直結していませんでしても、 もし其のデバイスドライバを各PCへとインストールしていましたら、 USB接続のローカルプリンタの場合と同じ様に、 印刷の設定の画面に其のネットワークプリンタもが登場し得ますので、 上記の内容の妥当性を私は想像していました。 でも、インストール後の"CubePDF( http://www.cube-soft.jp/cubepdf/ )"等さえもが、印刷の設定画面で選択され得ますね。 従いまして、私の根本的な誤解の解消の為に、 せめてヒントだけでも賜れますと、幸甚に存じます。

  • AIX ソケット関連のシステムコールについて

    IBM社のRS/6000を使っています。ソケット関連のシステムコールで相手接続先のマシンが接続されていないとき、(ケーブルをはずした時)ソケット接続で利用しているAIXの下記のシステムコール処理時間(応答時間)はどのくらいかかるんでしょうか?(システムが応答するerrnoはコネクションタイムアウト78になります) またこのような関連したサイト、本などご紹介下さい。

  • 画面が表示されません

    現在使ってるPCはe-machinesのJ4432です。 今回PCIエクスプレス×1のグラフィックボードG550(マトロックス社)をつけてみたのですが、画面が全く表示されません。 BIOS画面を見て Integrated Peripherals > init display first はPCIEXになってます。 システムのデバイスマネージャのディスプレイアダプタのところを見るとG550と表示されていて、正常に動作していると表示されます。 設定が間違っているのか、初期不良なのか判断できません。 どなたか助けてください。 よろしくお願いします。

  • 表示画面が小さくなってしまいました。

    SONY VAIOのPCV-W101/Wを使用しています。 誤って、何かを(たぶんディスプレイドライバだと思うんですが…)アンインストールした際に、画面が中央に小さくしか表示されなくなってしまいました。画面の周りは真っ黒です。 元道り、フル画面で表示するにはどうしたらいいでしょうか? そもそも、原因はディスプレイドライバのアンインストールであっているんでしょうか? かなり困っています。助けてくださーい!

  • 画面の表示が小さく荒く暗いです。

    ある日突然、パソコンの電源を入れると 画面の表示が小さく、色数も少なくなってしまいました。 画面のプロパティでは解像度は小640×480ピクセルで 大にすると画面の表示がもっと小さくなり 色も暗くなり見えなくなってしまいます。 画面の色は高24ビットになっております。 写真画像などとんでもなく荒く暗いです。 友達に作ってもらった自作PCです。 ディスプレイアダプタはsis5598/6326 モニタはNECのDV15A1 OSはWindowsXPです。 デバイスマネージャにエラーはありません。 ドライバを入れ直すと良いかと思い 探してみましたが見つける事が出来ませんでした。 どうすれば回復するのでしょうか。 どうかよろしくお願い致します。

  • 画面が表示されません

    画面が表示されません Windows7を使用しているのですが、画面が全く表示されずに困っています(>_<) 現象としては ・BIOSは表示される ・Windows起動中に下部に表示される流れるバー(?)は表示される ・しかしWindowsのロゴアニメーションは表示されない ・その後Windowsの起動音はなるも画面は真っ暗、厳密に言うと  メインディスプレイ(DVI):ディスプレイ信号は認識しているも真っ暗  サブディスプレイ(DVI):ディスプレイ信号すら認識していない状態 といった形でログオン画面以降が表示されません いろいろ検証を行ってみましたが ・セーフモードでは表示可能 ・リモートデスクトップでも表示可能 なのでディスプレイドライバの問題と判断し、セーフモードでディスプレイドライバを一度削除しました。 すると再起動後、通常起動で画面が表示されるようになったのですが・・・ Windowsが新しいディスプレイドライバを認識しました、と表示し再起動を求められ再起動すると最初の現象(画面が表示されない)に戻ってしまいます。 何か対策はございませんでしょうか? ご助言お願いいたしますm(__)m 最後にPCの仕様です OS:Windows7 Ultimate(64bit) CPU:Intel Core i7-860 メモリ:8GB(DDR3-10600 2GB × 4) SSD:ATADA AS596B-64GM-C(64GB) マザボ:P55-SD50(P55 1156 ATX DR3) グラボ:GALAXY 95XJF9HS8GGV(GeForce GTX295)

  • 2つのDisplayに画面表示させたい

     今晩は、早速ですが宜しくお願いします。    ノート(98SE)のDisplayが小さいので、おなじ画面を別のDisplayに表示させたいのですが、できません。  ノートのDisplayには通常の画面が表示されるのですが、別のDisplayには「背景」しか表示されません。ワードなどのアプリケーションを開いても何も変わりません。  また再起動などを繰り返すと、マウスポインターが別のDisplayのほうにのみ表示され、ノートのほうには全く表示されない時もあります。  この辺の設定の仕方が全くわかりません、色々と本でも調べましたが詳しい本が見当たりません。  だれか教えて下さい、是非お願いします。

  • 画面が表示できません

    DELLのINSPIRON8500にOSのみをクリーンインストールしましたがビデオドライバーをインストールすると本体側の画面が表示できません。どうすればいいのでしょうか? PC:INSPIRON8500 ビデオチップ:Mobility Radeon 9000 OS:XP/2000(どちらでも同じ症状です) ドライバ:DELL純正/OMEGAドライバ(どちらでも同じ症状です) [詳細な症状] 1.PCを起動するとDELLのメーカーロゴ、Windowsの起動画面は表示されるものの、その後、画面が真っ黒になり、何も表示されない。OSは正常起動している。 2.外部モニタを接続すると外部モニタには正常に表示可能。 3.Fn+F8キーでモニタの切り替えを行っても切り替わらない。 4.SafeModeで起動後、ディスプレイドライバを削除し、再起動するとディスプレイドライバが自動的にインストールされ、VGA、8bitカラーで表示されるが解像度、色数のどちらかを変更すると画面が真っ黒になる。 ドライバの問題なら外部ディスプレイへの出力もできないはずだし、ノートの本体モニタの問題ならメーカーロゴ、Windowsの起動画面も表示できないはずなのですが・・・。正直わけがわかりません。よろしくお願いします。

専門家に質問してみよう