Skip to content
Takym (たかやま) edited this page Jul 11, 2021 · 15 revisions

Takym > QA

質疑応答

このページでは低レイヤに関する質問とその回答をまとめています。 下記に該当する質問が無い場合は Slack の #初心者質問相談 チャンネルに訪れてみてください。

目次

質問: 機械語命令に数字が使われる事はありますか?

回答: あります。

例えば x86 では下記の様な命令があります。

命令 説明 (概略) 参考
CMPXCHG8B レジスタとメモリ上の値を比較し等しければ交換します。 https://www.felixcloutier.com/x86/cmpxchg8b:cmpxchg16b
CRC32 巡回冗長検査します。 https://www.felixcloutier.com/x86/crc32
INT3 デバッグ時に使用されます。 https://x86.puri.sm/html/file_module_x86_id_142.html
UD2 無効命令例外を発生させます。 https://mudongliang.github.io/x86/html/file_module_x86_id_318.html

質問: GCC のインラインアセンブラの "a"(arg0)"Nd"(arg1) は何を意味しますか?

回答: オペランド制約を意味します。
  • aEAX レジスタを表します。
  • dEDX レジスタを表します。
  • N は8ビット即値の命令エンコーディングを優先する事を表します。
    • IN 命令と OUT 命令で使用されます。
  • NdNd の両方を指定しています。

参考

補足

これは GCC における仕様です。 Microsoft Visual Cインラインアセンブラの仕様とは異なります。


質問: CPU動作モードはどの様にして決定・判定しますか?

回答: 区画記述子(セグメント・ディスクリプタ、Segment Descriptor)の属性から決定・判定します。

x86 での区画記述子は下記の書式になります。

31...24 23 22 21 20 19...16 15 14...13 12 11...8 7...0
Base 31:24 G D/B L AVL Seg. Limit 19:16 P DPL S Type Base 23:16
31...16 15...0
Base Address 15:00 Segment Limit 15:00
  • G (Granularity) - 粒度。0 の場合は 1 B 単位で設定し、1 の場合は 4 KB 単位で設定する。
  • D/B (Default operation size) - 既定の制御ビット数。0 の場合は16ビット、1 の場合は32ビット。
  • L (64-bit code segment) - 1 の場合は64ビット。(IA-32e のみ)
  • AVL (Available for use by system software)
  • P (Segment present) - セグメントが存在する場合は 1、存在しない場合は 0
  • DPL (Descriptor privilege level) - 特権レベルを0~3で指定する。
  • S (Descriptor type) - 0 の場合はシステム、1 の場合はコードまたはデータ。

出典:https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html、ページ:Vol. 3A 3-9 下部から Vol. 3A 3-12 上部、参照日:2021/07/11


質問: C言語で構造体のアライメントを無効化する方法を教えてください。

回答: 属性 __attribute__((packed)) を構造体に付与します。
  • 下記の様に属性を指定します。
     typedef struct _STRUCT_A_ {
     	unsigned int   id;
     	unsigned char *name;
     } __attribute__((packed)) StructA;
  • Microsoft Visual C では下記の様に #pragma pack を使って記述できます。
     #pragma pack(1)
    
     typedef struct _STRUCT_A_ {
     	unsigned int   id;
     	unsigned char *name;
     } StructA;
    
     #pragma pack()

補足

データ構造アライメントはメモリ上のデータを効率的に配置する為に利用されています。


質問: INT 0xXX 命令で呼び出されるコードを読む方法を教えてください。

回答: 環境に依存しますが、デバッガで覗く事ができます。

INT 0xXX 命令にブレークポイントを貼り、デバッガを使ってコードを覗く事ができます。 実機でデバッグを行う場合は専用の機器が必要になる可能性があります。 仮想環境でデバッグを行う場合は QEMUGDB を接続すれば良いでしょう。 もしくはオープンソースの実装を読む事もできます。

Legacy BIOS のコードを読む場合

OS のコードを読む場合


質問: リアルモードで BIOS (INT 0x10 命令) を使わずに描画処理を行う方法はありますか?

回答: ありますが、難易度は高いです。

BIOS (INT 0x10 命令) を使わずに描画処理を行うには下記の方法が考えられます。

  • グラフィックコントローラ、ビデオチップ、GPU等の仕様書を入手する。
    • 仕様書は有料である場合や公開されていない場合もあります。
  • X Window System 等既存のオープンソースシステムを利用または解析する。

補足

BIOS ROM に保存されているコードの解析は利用規約や著作権に抵触する可能性があります。


質問: 「あ」という文字のコードポイントは Unicode では U+3042 ですが、「あ」と書かれたファイルには 30 42 という値は見つかりません。

回答: UTF-16BE または UTF-32BE 以外の文字コードで保存されている可能性があります。

Unicode では必ずコードポイントと同じ値がファイルに保存される訳では無く、通常は UTF-8UTF-16UTF-32 のいずれかに符号化してから保存されます。 「あ」(U+3042)という文字の場合は文字コード毎に下記の様に変換されます。

  • UTF-8: E3 81 82
  • UTF-16LE: 42 30
  • UTF-16BE: 30 42
  • UTF-32LE: 42 30 00 00
  • UTF-32BE: 00 00 30 42

補足

C言語の型 wchar_t はワイド文字型であり、どの文字コードを使うかは規定されておらず、環境依存になります。コンパイラやOSなどにより異なります。 上記で挙げた文字コードではない可能性もあります。 どの文字コードが使われるかは適宜確認する必要があります。


質問: 立方体を回転させるプログラムの作り方を教えてください。

回答: こちらのページを参考にしてください。

(書きかけ...)


Clone this wiki locally