-
Notifications
You must be signed in to change notification settings - Fork 5
OpeLa Language Specification
Kota UCHIDA edited this page Aug 28, 2020
·
41 revisions
IDT の 21 に割り込みハンドラを登録し,割り込み許可(sti)する例です。
// パディングを絶対に入れない構造体の定義
// foo'bar は特別な構文で,接頭辞 foo が共通するメンバがグループ化される
type idtEntry packed_struct {
Offset'Low address16[15:0]
SegmentSelector uint16
IST uint3
_ uint5
Type uint4
_ uint1
DPL uint2
P uint1
Offset'Middle address16[31:16]
Offset'High address32[63:32]
_ uint32
}
// こちらは適切にパディングが入る構造体
type stackFrame struct {
SS uint16
SP address
Flags uint64
CS uint16
IP address
}
// グローバル変数
var (
idt idtEntry[256]
)
func notifyEndOfInterrupt() {
// 組み込みの Atomic 型を使ってレジスタアクセス
eoi *Atomic<uint32> := address(0xfee000b0)
eoi->Store(0);
// same as: *Atomic<uint32>(address(0xfee000b0))->Store(0)
}
// interrupt service routine
isr intHandler21(stackFrame *stackFrame) {
Printk("INT21 CS:RIP = {:02x}:{:08x}\n", stackFrame->CS, stackFrame->IP)
notifyEndOfInterrupt()
}
func main(argc int, argv *byte) {
idt[21] = {
.offset = &intHandler21, .segment_selector = 1 * 8,
.type = 14, .dpl = 0, .p = 1
}
idtr packed_struct { _ uint16, _ address } := { sizeof(idt) - 1, &idt }
intrin.Lidt(&idtr)
intrin.Sti()
for {
intrin.Hlt()
}
}
- intN/uintN: N ビット幅の符号付き/符号無し整数
- byte: uint8 の別名
- address: ネイティブ幅のアドレス型
- addressN: N ビット幅のアドレス型
他の言語にない特徴的な型として address がある。アドレスはポインタから型情報を取り除いたものである。C の void*
に近い。
任意のポインタと address は相互に暗黙的に変換可能。
address から整数へは暗黙的に変換可能。
整数から address へは明示的なキャスト address(整数)
が必要。
- type Name T: T という型に Name と言う名前を付ける。Name は T とは異なる型となる。
- struct {..}: 構造体型
- packed_struct {..}: パディングが無い構造体型
8 ビット以上で,かつ 2 の累乗のビット幅を持つ整数型(int8, int16, int32, int64)は,自身のバイト数によってアラインされる。 8 ビット未満か,2 の累乗ではないビット幅の整数型はアラインされない(= 前のメンバに連続して配置される)
ページエントリのアドレスフィールドのように,下位 N ビットをマスクして読み書きすべきフィールドを定義できる。
type PageEntry struct {
P uint1
RW uint1
US uint1
PWT uint1
PCD uint1
A uint1
D uint1
PAT uint1
G uint1
_ uint3
Addr address64[63:12]
}
func f() {
var e PageEntry
e.Addr = 0x12345
assert(e.Addr == 0x12000)
}