LSL - 載入段限制

操作碼

指令

說明

0F 03 /r

LSL r16,r/m16

載入:r16 段限制與選擇器 r/m16

0F 03 /r

LSL r32,r/m32

載入:r32 段界限,選擇器 r/m32

說明

從第二個運算元(源運算元)指定的段描述符將規則的段限制載入到第一個運算元(目標運算元),並設定 EFLAGS 暫存器中的 ZF 標誌。源運算元(可以是暫存器或記憶體位置)包含要訪問的段描述符的段選擇器。目標運算元是通用暫存器。

作為載入過程的一部分,處理器會執行訪問檢查。載入到目標暫存器之後,軟體就可以比較段限制與指針的偏移量。

段限制是一個 20 位值,由段描述符中的位元組 0、1 以及位元組 6 的頭 4 位組成。如果描述符有位元組粒度的段限制(粒度標誌設定為 0),則將位元組粒度的值(位元組限制)載入到目標運算元。如果描述符有頁粒度的段限制(粒度標誌設定為 1),則將頁粒度的限制(頁限制)載入到目標運算元之前,LSL 指令會將它轉譯成位元組限制。轉譯的執行過程是,將 20 位“原始”限制左移 12 位,並用 1 填充低 12 位。

運算元大小為 32 位時,則將 32 位位元組限制儲存到目標運算元。運算元大小為 16 位時,會計算 32 位有效限制;不過,高 16 位將被截斷,只有低 16 位會載入到目標運算元。

將段限制載入到目標暫存器之前,此指令會執行以下檢查:

檢查段選擇器是否為空。檢查段選擇器指向的描述符是否在訪問的 GDT 或 LDT 限制範圍內。所有的程式碼與數據段描述符對 LSL 指令都有效(能夠訪問)。有效的特殊段與門描述符型別見下表。如果段不是相容程式碼段,則指令會檢查在 CPL 處是否可以看見指定的段描述符(即檢查段選擇器的 CPL 與 RPL 是否小於或等於段選擇器的 DPL)。

如果指令不能訪問段描述符,或是其型別對於此指令而言無效,則清除 ZF 標誌,並且不將任何值載入到目標運算元。

型別

名稱

有效

0

保留

1

可用的 16 位 TSS

2

LDT

3

正忙的 16 位 TSS

4

16 位呼叫門

5

16 位/32 位任務門

6

16 位中斷門

7

16 位陷阱門

8

保留

9

可用的 32 位 TSS

A

保留

B

正忙的 32 位 TSS

C

32 位呼叫門

D

保留

E

32 位中斷門

F

32 位陷阱門

操作

IF SRC[Offset) > descriptor table limit
THEN ZF 0; FI;
Read segment descriptor;
IF SegmentDescriptor(Type) conforming code segment
AND (CPL > DPL) OR (RPL > DPL)
OR Segment type is not valid for instruction
THEN
ZF 0
ELSE
temp SegmentLimit([SRC]);
IF (G 1)
THEN
temp ShiftLeft(12, temp) OR 00000FFFH;
FI;
IF OperandSize 32
THEN
DEST temp;
ELSE (*OperandSize 16*)
DEST temp AND FFFFH;
FI;
FI;

影響的標誌

如果段限制載入成功則 ZF 標誌置為 1;否則清除為 0。

保護模式異常

#GP(0) - 如果記憶體運算元有效地址超出 CS、DS、ES、FS 或 GS 段限制。如果 DS、ES、FS、或 GS 暫存器用於訪問記憶體,並且它包含空的段選擇器。

#SS(0) - 如果記憶體運算元有效地址超出 SS 段限制。

#PF(錯誤程式碼) - 如果發生頁錯誤。

#AC(0) - 如果啟用對齊檢查並在目前特權級別為 3 時進行未對齊的記憶體引用。

實地址模式異常

#UD - LSL 指令在實地址模式中無法識別。

虛 8086 模式異常

#UD - LSL 指令在虛 8086 模式中無法識別。