# DEFINE _ set_gate (gate_addr, type, DPL, ADDR, SEG )/
Do {/
Int _ D0, _ D1 ;/
_ ASM _ volatile _ ("movw % dx, % ax/n/t "/
"Movw % 4, % dx/n/t "/
"Movl % eax, % 0/n/t "/
"Movl % edX, % 1 "/
: "= M" (* (long *) (gate_addr ))),/
"= M" (* (1 + (long *) (gate_addr), "= & A" (_ D0), "= & D" (_ D1)/
: "I" (short) (0x8000 + (DPL <13) + (type <8 ))),/
"3" (char *) (ADDR), "2" (SEG) <16 ));/
} While (0)
Analysis:
Output:
* (Gate_addr) 0%
* (1 + gate_addr) 1%
D0 2% (SEG) <16 stored in eax (= &)
D1 3% (char *) ADDR) is stored in EDX (= & D)
Inout:
(0x800 + (DPL <13) + (type <8 ))
Movw % dx, % ax shift edX's low 16 to eax's low 16, that is, moving (char *) ADDR's low 16 to eax
In this way, the value in eax is (SEG) <16 | ADDR (0-15)
Movw % 4, % DX move (0x800 + (DPL <13) + (type <8) to edX
In this way, the value of edX is ADDR (16-31) | (0x800 + (DPL <13) + (type <8 ))
Movl % eax, % 0 write eax * (gate_addr) as the low 32-bit Interrupt Descriptor
Movl % edX, % 1 Write edX * (1 + gate_addr) * (gate_addr + 1) as the 32-bit high of the Interrupt Descriptor
In this way, the content of the Interrupt Descriptor is:
ADDR (31-16) | (0x800 + (DPL <13) + (type <8) (63-32)
(SEG) <16 | ADDR (0-15) (31-0)