----------------------------
title : LDS, LES, LFS, LGS, LSSs (Intel x86/64 assembly instruction)
cat_title : LDS, LES, LFS, LGS, LSS
ref_title : LDS, LES, LFS, LGS, LSS
published : 2020-09-01
path : /X86-64 명령어 레퍼런스/L
publish_date: 2020-09-01
----------------------------


#@ LDS, LES, LFS, LGS, LSS

**Load Far Pointer**

```lec-info
아래 표를 해석하는 방법은 [x86-64 명령어 레퍼런스 읽는 법](/316) 글을 참조하시기 바랍니다.
```

|**Opcode**|**Instruction**|**Op/ **\newline{}**En**|**64-Bit **\newline{}**Mode**|**Compat/**\newline{}**Leg Mode**|**Description**|
|----------|---------------|------------------------|-----------------------------|---------------------------------|---------------|
|C5 /r|`LDS` \tooltip{r16}{2 바이트 짜리 범용 레지스터를 의미 (AX, CX, DX, BX, SP, BP, SI, DI). 64 비트 모드의 경우 추가적으로 R8 부터 R15 까지 가능.} \tooltip{m16:16}{Far pointer 로 표현된 메모리 데이터로, : 왼쪽에 있는 값은 포인터의 세그먼트 셀렉터를, 오른쪽 값은 해당 세그먼트 안의 오프셋을 의미한다.} |RM|Invalid|Valid|Load DS:r16 with far pointer from memory.|
|C5 /r|`LDS` \tooltip{r32}{4 바이트 짜리 범용 레지스터를 의미 (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI). 64 비트 모드의 경우 추가적으로 R8D 부터 R15D 까지 가능.} \tooltip{m16:32}{To-m16:16} |RM|Invalid|Valid|Load DS:r32 with far pointer from memory.|
|0F B2 /r|`LSS` \tooltip{r16}{2 바이트 짜리 범용 레지스터를 의미 (AX, CX, DX, BX, SP, BP, SI, DI). 64 비트 모드의 경우 추가적으로 R8 부터 R15 까지 가능.} \tooltip{m16:16}{Far pointer 로 표현된 메모리 데이터로, : 왼쪽에 있는 값은 포인터의 세그먼트 셀렉터를, 오른쪽 값은 해당 세그먼트 안의 오프셋을 의미한다.} |RM|Valid|Valid|Load SS:r16 with far pointer from memory.|
|0F B2 /r|`LSS` \tooltip{r32}{4 바이트 짜리 범용 레지스터를 의미 (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI). 64 비트 모드의 경우 추가적으로 R8D 부터 R15D 까지 가능.} \tooltip{m16:32}{To-m16:16} |RM|Valid|Valid|Load SS:r32 with far pointer from memory.|
|REX + 0F B2 /r|`LSS` \tooltip{r64}{8 바이트 짜리 범용 레지스터를 의미 (RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, R8–R15). 이들은 64비트 모드에서만 사용 가능하다.} \tooltip{m16:64}{To-m16:16} |RM|Valid|N.E.|Load SS:r64 with far pointer from memory.|
|C4 /r|`LES` \tooltip{r16}{2 바이트 짜리 범용 레지스터를 의미 (AX, CX, DX, BX, SP, BP, SI, DI). 64 비트 모드의 경우 추가적으로 R8 부터 R15 까지 가능.} \tooltip{m16:16}{Far pointer 로 표현된 메모리 데이터로, : 왼쪽에 있는 값은 포인터의 세그먼트 셀렉터를, 오른쪽 값은 해당 세그먼트 안의 오프셋을 의미한다.} |RM|Invalid|Valid|Load ES:r16 with far pointer from memory.|
|C4 /r|`LES` \tooltip{r32}{4 바이트 짜리 범용 레지스터를 의미 (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI). 64 비트 모드의 경우 추가적으로 R8D 부터 R15D 까지 가능.} \tooltip{m16:32}{To-m16:16} |RM|Invalid|Valid|Load ES:r32 with far pointer from memory.|
|0F B4 /r|`LFS` \tooltip{r16}{2 바이트 짜리 범용 레지스터를 의미 (AX, CX, DX, BX, SP, BP, SI, DI). 64 비트 모드의 경우 추가적으로 R8 부터 R15 까지 가능.} \tooltip{m16:16}{Far pointer 로 표현된 메모리 데이터로, : 왼쪽에 있는 값은 포인터의 세그먼트 셀렉터를, 오른쪽 값은 해당 세그먼트 안의 오프셋을 의미한다.} |RM|Valid|Valid|Load FS:r16 with far pointer from memory.|
|0F B4 /r|`LFS` \tooltip{r32}{4 바이트 짜리 범용 레지스터를 의미 (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI). 64 비트 모드의 경우 추가적으로 R8D 부터 R15D 까지 가능.} \tooltip{m16:32}{To-m16:16} |RM|Valid|Valid|Load FS:r32 with far pointer from memory.|
|REX + 0F B4 /r|`LFS` \tooltip{r64}{8 바이트 짜리 범용 레지스터를 의미 (RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, R8–R15). 이들은 64비트 모드에서만 사용 가능하다.} \tooltip{m16:64}{To-m16:16} |RM|Valid|N.E.|Load FS:r64 with far pointer from memory.|
|0F B5 /r|`LGS` \tooltip{r16}{2 바이트 짜리 범용 레지스터를 의미 (AX, CX, DX, BX, SP, BP, SI, DI). 64 비트 모드의 경우 추가적으로 R8 부터 R15 까지 가능.} \tooltip{m16:16}{Far pointer 로 표현된 메모리 데이터로, : 왼쪽에 있는 값은 포인터의 세그먼트 셀렉터를, 오른쪽 값은 해당 세그먼트 안의 오프셋을 의미한다.} |RM|Valid|Valid|Load GS:r16 with far pointer from memory.|
|0F B5 /r|`LGS` \tooltip{r32}{4 바이트 짜리 범용 레지스터를 의미 (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI). 64 비트 모드의 경우 추가적으로 R8D 부터 R15D 까지 가능.} \tooltip{m16:32}{To-m16:16} |RM|Valid|Valid|Load GS:r32 with far pointer from memory.|
|REX + 0F B5 /r|`LGS` \tooltip{r64}{8 바이트 짜리 범용 레지스터를 의미 (RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, R8–R15). 이들은 64비트 모드에서만 사용 가능하다.} \tooltip{m16:64}{To-m16:16} |RM|Valid|N.E.|Load GS:r64 with far pointer from memory.|
### Instruction Operand Encoding


|Op/En|Operand 1|Operand 2|Operand 3|Operand 4|
|-----|---------|---------|---------|---------|
|RM|ModRM:reg (w)|ModRM:r/m (r)|NA|NA|
### Description


Loads a far pointer (segment selector and offset) from the second operand (source operand) into a segment register and the first operand (destination operand). The source operand specifies a 48-bit or a 32-bit pointer in memory depending on the current setting of the operand-size attribute (32 bits or 16 bits, respectively). The instruction opcode and the destination operand specify a segment register/general-purpose register pair. The 16-bit segment selector from the source operand is loaded into the segment register specified with the opcode (DS, SS, ES, FS, or GS). The 32-bit or 16-bit offset is loaded into the register specified with the destination operand.

If one of these instructions is executed in protected mode, additional information from the segment descriptor pointed to by the segment selector in the source operand is loaded in the hidden part of the selected segment register.

Also in protected mode, a NULL selector (values 0000 through 0003) can be loaded into DS, ES, FS, or GS registers without causing a protection exception. (Any subsequent reference to a segment whose corresponding segment register is loaded with a NULL selector, causes a general-protection exception (#GP) and no memory reference to the segment occurs.)

In 64-bit mode, the instruction's default operation size is 32 bits. Using a REX prefix in the form of REX.W promotes operation to specify a source operand referencing an 80-bit pointer (16-bit selector, 64-bit offset) in memory. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). See the summary chart at the beginning of this section for encoding data and limits.


### Operation

```info-verb
64-BIT_MODE
    IF SS is loaded 
          THEN 
                IF SegmentSelector = NULL and ( (RPL = 3) or 
                            (RPL != 3 and RPL != CPL) )
                      THEN #GP(0);
                ELSE IF descriptor is in non-canonical space
THEN #GP(0); FI;
                ELSE IF Segment selector index is not within descriptor table limits
                            or segment selector RPL != CPL
                            or access rights indicate nonwritable data segment
                            or DPL != CPL
                      THEN #GP(selector); FI;
                ELSE IF Segment marked not present
                      THEN #SS(selector); FI;
                FI;
                SS <- SegmentSelector(SRC);
                SS <- SegmentDescriptor([SRC]);
    ELSE IF attempt to load DS, or ES 
          THEN #UD;
    ELSE IF FS, or GS is loaded with non-NULL segment selector
          THEN IF Segment selector index is not within descriptor table limits
                or access rights indicate segment neither data nor readable code segment
                or segment is data or nonconforming-code segment 
                and ( RPL > DPL or CPL > DPL)
                      THEN #GP(selector); FI;
                ELSE IF Segment marked not present
                      THEN #NP(selector); FI;
                FI;
                SegmentRegister <- SegmentSelector(SRC) ;
                SegmentRegister <- SegmentDescriptor([SRC]);
          FI;
    ELSE IF FS, or GS is loaded with a NULL selector:
          THEN
                SegmentRegister <- NULLSelector;
                SegmentRegister(DescriptorValidBit) <- 0; FI; (* Hidden flag; not accessible by software *)
    FI;
    DEST <- Offset(SRC);
PREOTECTED MODE OR COMPATIBILITY MODE;
    IF SS is loaded 
          THEN 
                IF SegementSelector = NULL 
                      THEN #GP(0);
                ELSE IF Segment selector index is not within descriptor table limits
                            or segment selector RPL != CPL
                            or access rights indicate nonwritable data segment
                            or DPL != CPL
                      THEN #GP(selector); FI;
                ELSE IF Segment marked not present
                      THEN #SS(selector); FI;
                FI;
                SS <- SegmentSelector(SRC);
                SS <- SegmentDescriptor([SRC]);
    ELSE IF DS, ES, FS, or GS is loaded with non-NULL segment selector
          THEN IF Segment selector index is not within descriptor table limits
                or access rights indicate segment neither data nor readable code segment
                or segment is data or nonconforming-code segment 
                and (RPL > DPL or CPL > DPL) 
                      THEN #GP(selector); FI;
ELSE IF Segment marked not present
                      THEN #NP(selector); FI;
                FI;
                SegmentRegister <- SegmentSelector(SRC) AND RPL;
                SegmentRegister <- SegmentDescriptor([SRC]);
          FI;
    ELSE IF DS, ES, FS, or GS is loaded with a NULL selector:
          THEN
                SegmentRegister <- NULLSelector;
                SegmentRegister(DescriptorValidBit) <- 0; FI; (* Hidden flag; not accessible by software *)
    FI;
    DEST <- Offset(SRC);
Real-Address or Virtual-8086 Mode
    SegmentRegister <- SegmentSelector(SRC); FI;
    DEST <- Offset(SRC);
```
### Flags Affected


None


### Protected Mode Exceptions

#### #UD
* If source operand is not a memory location.
* If the LOCK prefix is used.

#### #GP(0)
* If a NULL selector is loaded into the SS register.
* If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
* If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment selector.

#### #GP(selector)
* If the SS register is being loaded and any of the following is true: the segment selector index is not within the descriptor table limits, the segment selector RPL is not equal to CPL, the segment is a non-writable data segment, or DPL is not equal to CPL.
* If the DS, ES, FS, or GS register is being loaded with a non-NULL segment selector and any of the following is true: the segment selector index is not within descriptor table limits, the segment is neither a data nor a readable code segment, or the segment is a data or noncon-forming-code segment and both RPL and CPL are greater than DPL.

#### #SS(0)
* If a memory operand effective address is outside the SS segment limit.

#### #SS(selector)
* If the SS register is being loaded and the segment is marked not present.

#### #NP(selector)
* If DS, ES, FS, or GS register is being loaded with a non-NULL segment selector and the segment is marked not present.

#### #PF(fault-code)
* If a page fault occurs.

#### #AC(0)
* If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.

### Real-Address Mode Exceptions

#### #GP
* If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.

#### #SS
* If a memory operand effective address is outside the SS segment limit.

#### #UD
* If source operand is not a memory location.
* If the LOCK prefix is used.

### Virtual-8086 Mode Exceptions

#### #UD
* If source operand is not a memory location.
* If the LOCK prefix is used.

#### #GP(0)
* If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.

#### #SS(0)
* If a memory operand effective address is outside the SS segment limit.

#### #PF(fault-code)
* If a page fault occurs.

#### #AC(0)
* If alignment checking is enabled and an unaligned memory reference is made.

### Compatibility Mode Exceptions



Same exceptions as in protected mode.


### 64-Bit Mode Exceptions

#### #GP(0)
* If the memory address is in a non-canonical form.
* If a NULL selector is attempted to be loaded into the SS register in compatibility mode.
* If a NULL selector is attempted to be loaded into the SS register in CPL3 and 64-bit mode.
* If a NULL selector is attempted to be loaded into the SS register in non-CPL3 and 64-bit mode where its RPL is not equal to CPL.

#### #GP(Selector)
* If the FS, or GS register is being loaded with a non-NULL segment selector and any of the following is true: the segment selector index is not within descriptor table limits, the memory address of the descriptor is non-canonical, the segment is neither a data nor a readable code segment, or the segment is a data or nonconforming-code segment and both RPL and CPL are greater than DPL.
* If the SS register is being loaded and any of the following is true: the segment selector index is not within the descriptor table limits, the memory address of the descriptor is non-canonical, the segment selector RPL is not equal to CPL, the segment is a nonwritable data segment, or DPL is not equal to CPL.

#### #SS(0)
* If a memory operand effective address is non-canonical

#### #SS(Selector)
* If the SS register is being loaded and the segment is marked not present.

#### #NP(selector)
* If FS, or GS register is being loaded with a non-NULL segment selector and the segment is marked not present.

#### #PF(fault-code)
* If a page fault occurs.

#### #AC(0)
* If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.

#### #UD
* If source operand is not a memory location.
* If the LOCK prefix is used.
