6 章: 分割コンパイルと割込み処理
分割コンパイルはこれまでに幾度となくやってきて、そのメリットなんかも充分に理解できているのでさっと読み飛ばしました。
6 章のメインは、機能の GDT, IDT の説明と、割込みハンドラの作成。
まずは GDT から。これは
- セグメントのサイズ
- セグメントの開始番地
- セグメントの管理用属性
を 8 バイトに設定します。ただし、CPU の後方互換のためにサイズや開始番地は連続する領域ではなく、細切れに設定することになっています。今回のプログラムではこの設定を構造体を介して行っているのですが、特定のアドレス領域に C の構造体で値を設定する場合はメンバ変数のアライメントが気になりますね。なりませんか?私は気になります。
GDT の先頭アドレスは開発者が自由に決めることができますが、GDT を設定するための構造体は short, short, char * 4 の構成になっています。ということは先頭を奇数番地にしたらまずいんじゃないかなと思ったので…
実際にやってみた (トリビアの泉風で)。
結果、GDT の先頭アドレスを奇数番地にしても、とくにエラーもなく実行できてしまった…。
コンパイルして作られたアセンブラを見てみると、
MOV ESI,2555905 <-- GDT の先頭アドレス(奇数番地) MOV EBX,8191 L6: PUSH 0 PUSH 0 PUSH 0 PUSH ESI <-- 先頭アドレスをスタックに積む ADD ESI,8 CALL _set_segmdesc
とあって、_set_segmdesc では
_set_segmdesc: PUSH EBP MOV EBP,ESP PUSH EBX MOV EDX,DWORD [12+EBP] MOV ECX,DWORD [16+EBP] MOV EBX,DWORD [8+EBP] <-- 2555905 MOV EAX,DWORD [20+EBP] CMP EDX,1048575 JBE L17 SHR EDX,12 OR EAX,32768 L17: MOV WORD [EBX],DX <-- 奇数番地にワード書き込み
となっています。確かに L17 の時点で EBX には 2555905 が入っているから奇数アドレスへのワード書き込みで吹っ飛びそうな気がするんだけど…。x86 はアライメントルールなしですか?
ということで、はるばる Intel のサイトまで出かけて Pentium4 のドキュメント(pdf)を調べてみると 4.1.1 Alignment of Words, Doublewords, Quadwords, and Double Quadwords にこんな記述がありました。
Words, doublewords, and quadwords do not need to be aligned in memory on natural boundaries. The natural boundaries for words, double words, and quadwords are even-numbered addresses, addresses evenly divisible by four, and addresses evenly divisible by eight, respectively.
ということで、アライメントルールはないことが分かりました。
( ・∀・)つ〃∩ ヘェーヘェー
もちろん補足トリビアも用意してございます。上で引用した部分の続きには、
However, to improve the performance of programs, data structures (especially stacks) should be aligned on natural boundaries whenever possible. The reason for this is that the processor requires two memory accesses to make an unaligned memory access; aligned accesses require only one memory access.
とありました。アライメントルールはないものの境界を跨いだメモリアクセスなど出来るわけなく、実際には CPU が頑張ってと 2回メモリアクセスするので、(特にスタックへのアクセスは) 効率悪くなりまっせということらしいです。
( ・∀・)つ〃∩ ヘェーヘェー
私はアライメントエラーで吹っ飛ぶ CPU しか知らなかったので、ちょっと Intel 系 CPU の真面目さにちょっと感動しました。
以上、6-5 まで終了。割込みハンドラはこの後すぐ!
最近のコメント