2015年8月30日日曜日

【自作エミュレータで学ぶx86アーキテクチャ】書店に並ぶ様子まとめ

書店での目撃情報などが出てきたので、ここにまとめます。

書泉ブックタワー

丸善 日本橋店

ジュンク堂 渋谷店

ジュンク堂 池袋本店

有隣堂 ヨドバシAKIBA店

2015年8月22日土曜日

日本語キーボードを US 配列で使いつつ、変換/無変換キーで IME ON/OFF

僕はキーボードのキー配列は US 配列が好きです。なぜなら記号の位置などが JP 配列より綺麗だからです。JP 配列ではなぜか離れ離れになっている「'」と「"」、「;」と「:」が同じキーに割り当てられていたりします。

でも US 配列のキーボードはちょっと嫌いです。なぜなら「変換」「無変換」キーがないからです。そんなキーは普段使わない、という人もいるかもしれませんが、この 2 つのキーはカスタマイズにちょうどいいと思いませんか。US 配列キーボードのスペースバーは長すぎて無駄だと思いませんか。

僕は「変換」を IME のオンに、「無変換」を IME のオフに割り当てて使うのが好みなので、それらのキーがある JP 配列キーボードは必需品です。半角・全角キーは「今、どちらの設定だったか」を覚えておく必要があって、半角モードにしたいのに間違えて全角になってしまってイライラするのですが、IME のオンオフを別のキーにしておくことで、ステートレスな IME 切り替えを実現できます。(Mac の JP キーボードは最初からそうなっていて素敵ですね)

問題は JP 配列キーボード(例えば REALFORCE108UBK)の大部分のキーを US 配列として使いつつも、変換・無変換キーを有効化して IME オンオフに使うにはどうするかということです。Windows で通常の手順(Windows 8 でキーボードが英語配列キーボードとして認識される)でキーボードレイアウトを「101 キーボード」にしてしまうと、変換・無変換キーが存在しない純粋な US 配列キーボードとして扱われてしまって問題を解決できません。

そこで AX 配列(参考:右Altキーに[漢字]キーを割り当てる方法 )を使います。AX 配列とは参考記事に書いてある通り、 US 配列に必要最低限の変更を加えて(つまり記号の位置などを極力変更せず)日本語環境で使いやすくした配列であり、今回の問題にピッタリなのです。

AX 配列への変更は参考記事を参照していただくとして、ここでは AX 配列に変更した後にやるとよいキー配置変更を説明します。AX 配列に変更してみると分かると思いますが、JP 配列キーボードの「}]」キー(Enter の左下)を押すと「\」が入力されてしまったり、「\|」キー(Back Space の左)を押しても何も入力されなかったりと、少し不便です。さらに重要なことに、変換・無変換キーを IME の切り替えに割り当てることができない状態になっています。

ということでレジストリの HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout に「Scancode Map」というバイナリ値を書き込みます。
この方法は日本語キーボードを英語キーボードとして使う - Nikepを大いに参考にしています。Scancode Map は実際に押されたキーをどのキーに変換するかを定義するもので、上図の値は具体的に次の設定を表します。

  • 1D,00,3A,00 : 3A (Caps Lock) → 1D (Ctrl)
  • 3A,00,1D,00 : 1D (Ctrl) → 3A (Caps Lock)
  • 1C,00,2B,00 : 2B (JP }] key) → 1C (Enter)
  • 2B,00,7D,00 : 7D (JP |\ key) → 2B (JP }] key)
  • 36,00,73,00 : 73 (JP _\ key) → 36 (Right Shift)
  • 38,E0,70,00 : 70 (JP kana) → E0 38 (Right Alt)
  • 5B,00,79,00 : 79 (JP henkan) -> 5B
  • 5A,00,7B,00 : 7B (JP muhenkan) -> 5A
5B、5A はどうしてその値なのか良く分かりませんが、とりあえずその値に変換すると変換・無変換キーを変換・無変換キーとして認識するようになります。後は IME の設定を変えるだけです。

IME のプロパティから「詳細設定」画面を開き、キー設定の「変更」をクリックします。
変換と無変換が押されたときの挙動を「IME-オン」「IME-オフ」に対応付けます。
以上で設定は完了です。快適なキーボードライフをお過ごしください!

2015年8月14日金曜日

出版のお知らせ 『自作エミュレータで学ぶx86アーキテクチャ』

久しぶりのブログ更新となりました。
理由の一つは、ここ数ヶ月は暇さえあれば本の原稿を書いていたからです。

本のタイトルはちょっと長いですが
『自作エミュレータで学ぶx86アーキテクチャ コンピュータが動く仕組みを徹底理解!』
ということになりました。
8月28日に出版予定でございます。



2015年8月23日更新
Kindle 版が 2,152円+税で予約開始したようです。
自作エミュレータで学ぶx86アーキテクチャ コンピュータが動く仕組みを徹底理解!


共著の方(d-kamiさん)のブログでも紹介されています。
というわけで本を出版します - マイペースなプログラミング日記

タイトルの通り、この本はx86 CPUの機械語を実行するエミュレータソフトウェアを作りながらx86アーキテクチャを学んでいこうという本です。例えばinc [ebp-4]を機械語に変換するとff 45 fcになり、それぞれがオペコード、ModR/M、ディスプレースメントに対応することを学びます。ModR/Mの中も実はビット単位で意味があり、Mod、REG、R/Mに分かれているんだよという話もします。

2015年8月25日更新:
本書で作るエミュレータは x86 の中でも一部の機能を実装したとてもシンプルなものです。一言で表せば、オペランドサイズが 32 ビットのリアルモードエミュレータです。リアルモードの全命令を実装しているわけではありませんし、セグメント機構など高度な機能も実装しませんが、それでも C 言語で書いたプログラムを動かすことができるくらいの機能は持っています。人によっては物足りなく感じる方もいらっしゃると思いますが、本書は C 言語を学び終えたくらいの人が次に読む本を想定していますのでご了承ください。

CPUに閉じることなく、CPUとその周りとの関連も扱っています。x86 CPUはメインメモリにスタック構造を作ります。C言語入門した直後だとそもそもスタックを知らないかもしれませんので、一般的なスタックの話から始めて実際にメモリ上に作られるスタックフレームの話まで書いています。また、メモリより外の世界としてI/Oの話も扱います。CPUはI/Oを介して外界に繋がらなければ役立つ仕事はできません。エミュレータにin/out命令とキャラクタデバイスを実装し、実際にキーボード入力とディスプレイ出力を行えるようにしてみます。

最後の章では、実機でプログラムを実行する方法も説明しています。USBメモリのブートセクタに自作の機械語を書き込み、パソコンを起動させ、OSの力を借りずにプログラムを実行させます。BIOSの文字表示機能を使って、色付きの文字列を画面に表示させるのがゴールです。




この本はC言語の入門書を読み終わったくらいのレベルの人が読めることを目指して書いているため、C言語プログラミングで入門の次に知ると良さそうな事柄、例えばファイル分割の方法とか、printfで色付きの文字列を出力する方法なども扱っています。1章分のページをまるまる使って、アセンブリ言語の視点からポインタを学び直すので、C言語のポインタで躓いてしまった人にも何らかのひらめきを与えられる可能性があります。

また、本書を通してx86エミュレータというある程度の規模のソフトウェアを作りあげる経験を通して、読者のプログラミング能力を養おうという裏の目標もあったりします。手軽にx86の機械語を実行できる環境を作るという(ある意味)実用的なゴールを持ってプログラミングを行うことで、学習のための学習より効果の高いプログラミング練習になるでしょう。

お近くの書店で目についた際にチラ見していただければ幸いです。

最後に目次情報を載せておきます。

Chapter 1: C言語とアセンブリ言語

  • 1.1. C言語から機械語へ
  • 1.2. 機械語とアセンブリ言語
  • 1.3. 機械語に飛び込む
  • 1.4. アセンブリ言語を少し詳しく
  • 1.5. 基本のmov命令
  • 1.6. インクリメント専用のinc命令
  • 1.7. 16進数入門
  • 1.8. 2の補数入門

Chapter 2: ポインタとアセンブリ言語

  • 2.1. レジスタ
  • 2.2. メモリ
  • 2.3. 初めてのエミュレータ
  • 2.4. ポインタの復習
  • 2.5. ポインタに飛び込む
  • 2.6. 構造体とポインタ
  • 2.7. 不完全型とポインタ
  • 2.8. 関数ポインタ

Chapter 3: CPUがプログラムを実行する仕組み

  • 3.1. プログラムの配置
  • 3.2. エミュレータのorg対応
  • 3.3. プログラムの実行
  • 3.4. エミュレータのModR/M対応
  • 3.5. 無条件分岐命令
  • 3.6. call命令とスタック
  • 3.7. エミュレータのcall対応
  • 3.8. ローカル変数とスタック
  • 3.9. フラグレジスタと条件分岐命令
  • 3.10. エミュレータの条件分岐命令対応
  • 3.11. プログラムの繰り返し
  • 3.12. デバイスアクセス

Chapter 4: BIOSの仕組みと実機起動

  • 4.1. BIOS
  • 4.2. BIOSの実装
  • 4.3. 割り込み
  • 4.4. ブートセクタ
  • 4.5. PBRを見てみよう
  • 4.6. 実機で動かしてみよう