수색…


16 비트 레지스터

인텔이 원래 8086을 정의했을 때, 20 비트 주소 버스를 가진 16 비트 프로세서였습니다 (아래 참조). 그들은 8 개의 범용 16 비트 레지스터를 정의했지만 특정 명령어에 대해 특정 역할을 수행했습니다.

  • AX Accumulator 레지스터.
    많은 opcode가이 레지스터를 사용하거나 지정된 경우 더 빠릅니다.
  • DX 데이터 레지스터.
    이것은 때때로 AX 와 32 비트 값의 상위 16 비트로 결합되었습니다 (예 : 곱셈의 결과).
  • CX Count 레지스터.
    이것은 LOOPNE (동일하지 않은 경우 루프) 및 REP (반복 된 이동 / 비교)와 같은 루프에 대한 암시 적 카운터로 많은 루프 지향 명령어에서 사용되었습니다.
  • BX 베이스 레지스터.
    이것은 메모리에서 구조체의 기본을 인덱싱하는 데 사용할 수 있습니다. 위의 레지스터 중 어느 것도 메모리에 직접 인덱싱하는 데 사용할 수 없습니다.
  • SI 소스 인덱스 레지스터.
    이것은 특정 이동 및 비교 작업을위한 메모리에 대한 암시 적 소스 인덱스였습니다.
  • DI 목적지 인덱스 레지스터.
    이것은 특정 이동 및 비교 작업을위한 메모리에 대한 암시 적 대상 인덱스였습니다.
  • SP 스택 포인터 레지스터.
    이것은 세트에서 가장 적은 범용 레지스터입니다! 스택의 현재 위치는 PUSHPOP 작업에 명시 적으로 사용되었으며 암시 적으로 서브 루틴과 함께 CALLRET 대해서는 암시 적으로, 인터럽트 동안에는 암시 적으로 VERY로 지정되었습니다. 따라서 다른 용도로 사용하면 프로그램에 위험합니다!
  • BP 베이스 포인터 레지스터.
    서브 루틴이 다른 서브 루틴을 호출하면 스택은 여러 "스택 프레임"을 보유합니다. BP 는 현재 스택 프레임을 유지하는 데 사용될 수 있으며 새 서브 루틴이 호출되면 스택에 저장 될 수 있고 새로운 스택 프레임이 생성되어 사용되며 내부 서브 루틴에서 반환 될 때 이전 스택 프레임 값이 복원 될 수 있습니다 .

노트:

  1. 처음 세 레지스터는 메모리로 인덱싱하는 데 사용할 수 없습니다.

  2. BX , SIDI 를 기본적으로 현재 데이터 세그먼트에 색인화합니다 (아래 참조).

     MOV    AX, [BX+5]     ; Point into Data Segment
     MOV    AX, ES:[DI+5]  ; Override into Extra Segment
    
  3. DIMOVSCMPS 와 같은 메모리 - 메모리 연산에서 사용되는 경우에만 Extra Segment를 사용합니다 (아래 참조). 이것은 무시 될 수 없습니다.

  4. SPBP 는 기본적으로 스택 세그먼트 (아래 참조)를 사용합니다.

32 비트 레지스터

인텔은 80386을 생산할 때 16 비트 프로세서에서 32 비트 프로세서로 업그레이드했습니다. 32 비트 처리는 두 가지를 의미합니다. 조작되는 데이터는 모두 32 비트 였고 액세스되는 메모리 주소는 32 비트였습니다. 이를 위해 이전 프로세서와의 호환성을 유지하면서 완전히 새로운 프로세서 모드를 도입했습니다. 그것은 16 비트 모드 또는 32 비트 모드 중 하나 였지만 데이터, 어드레싱 또는 둘 모두에 대해 명령어별로이 모드를 오버라이드 할 수있었습니다!

우선, 32 비트 레지스터를 정의해야했습니다. 그들은 기존의 8 비트를 16 비트에서 32 비트로 확장하고 E 접두사 EAX , EBX , ECX , EDX , ESI , EDI , EBPESP 와 함께 "확장"이름을 제공함으로써이를 수행했습니다. 이러한 레지스터의 하위 16 비트는 이전과 동일하지만 레지스터의 상반부는 ADDCMP 와 같은 32 비트 연산에 사용할 수있었습니다. 상반부는 8 비트 레지스터와 마찬가지로 별도로 액세스 할 수 없었습니다.

Intel은 CMP AX,DX 16 비트 및 CMP EAX,EDX 32 비트 모드에서 동일한 연산 코드를 사용했기 때문에 별도의 16 비트 및 32 비트 모드가 있어야했습니다. ! 즉, 동일한 코드를 어느 모드에서도 실행할 수 없습니다.

"즉시 즉시 AX 로 이동"에 대한 opcode는 0xB8 이며 즉시 값의 2 바이트가 뒤에옵니다 : 0xB8 0x12 0x34

"Move immediate into EAX "에 대한 opcode는 0xB8 이며 그 뒤에 4 바이트 즉시 값 0xB8 0x12 0x34 0x56 0x78 . 0xB8 0x12 0x34 0x56 0x78

따라서 assember는 코드를 실행할 때 프로세서가 어떤 모드인지 알고 올바른 바이트 수를 출력해야합니다.

8 비트 레지스터

처음 네 개의 16 비트 레지스터 는 상위 및 하위 하프 바이트를 직접 고유 한 레지스터로 액세스 할 수 있습니다.

  • AHALAX 레지스터의 상한과 하한입니다.
  • BHBLBX 레지스터의 상한 및 하한입니다.
  • CHCLCX 레지스터의 상한 및 하한입니다.
  • DHDLDX 레지스터의 상한과 하한입니다.

이는 AH 또는 AL 을 변경하면 AX 도 즉시 AX 을 의미합니다. 또한 8 비트 레지스터의 모든 연산은 0xFF 에서 0x00 오버플로되어 AH 변경하지 않도록 AL 증가시키는 "파트너"에 영향을 미치지 않습니다.

64 비트 레지스터 에는 하위 바이트를 나타내는 8 비트 버전이 있습니다.

  • RSISIL
  • RDI 위한 DIL
  • RBP 대한 BPL
  • RSPSPL

레지스터 R8 ~ R15 에도 동일하게 적용됩니다. 각각의 하위 바이트 부분의 이름은 R8B ~ R15B 입니다.

세그먼트 레지스터

분할

인텔이 원래 8086을 설계 할 때 이미 16 비트 기능을 갖춘 8 비트 프로세서가 있었지만 진정한 16 비트 프로세서를 생산하려고했습니다. 그들은 또한 이미 존재했던 것보다 더 훌륭하고 능력있는 것을 생산하기를 원했기 때문에 16 비트 주소 지정 레지스터에 의해 암시 된 최대 65,536 바이트 이상의 메모리에 액세스 할 수 있기를 원했습니다.

원 세그먼트 레지스터

그래서 그들은 16 비트 주소 레지스터에 의해 인덱싱 된 64KB의 메모리 블록 인 "세그먼트"개념을 구현하여 총 메모리의 여러 영역을 다룰 수있었습니다. 이러한 세그먼트 기반을 유지하기 위해 세그먼트 레지스터가 포함되었습니다.

  • CS 코드 세그먼트 레지스터.
    이것은 현재 실행중인 코드의 세그먼트를 포함하며 암시 적 IP (명령어 포인터) 레지스터에 의해 인덱싱됩니다.
  • DS 데이터 세그먼트 레지스터.
    이것은 프로그램이 조작하는 데이터의 기본 세그먼트를 보유합니다.
  • ES 엑스트라 세그먼트 레지스터.
    전체 메모리에서 동시에 데이터를 조작하기 위해 두 번째 데이터 세그먼트를 보유합니다.
  • SS 스택 세그먼트 레지스터.
    현재 스택을 보유하는 메모리 세그먼트를 보유합니다.

세그먼트 크기?

세그먼트 레지스터는 모든 크기 일 수 있지만 16 비트 너비로 만들면 다른 레지스터와 쉽게 상호 운용 될 수 있습니다. 다음 질문은 : 세그먼트가 겹치면 그 세그먼트가 겹치게됩니까? 이 질문에 대한 대답은 액세스 할 수있는 총 메모리 크기를 결정합니다.

중복이 전혀 없다면 주소 공간은 32 비트 - 4 기가 바이트가 될 것입니다 - 당시로서는 전례가 없었습니다! 8 비트의 "자연스러운"오버랩은 24 비트 주소 공간 또는 16 메가 바이트를 생성합니다. 결국 인텔은 12 비트 오버랩으로 1 메가 바이트의 주소 공간을 만들어 프로세서에 4 개의 주소 핀을 추가로 저장하기로 결정했습니다.

더 많은 세그먼트 레지스터!

인텔은 80386을 설계 할 때 기존의 4 세그먼트 레지스터 세트가 지원할 수있는 프로그램의 복잡성으로 충분하지 않다는 사실을 알고있었습니다. 그래서 그들은 두 가지 더 추가했습니다.

  • FS 원거리 세그먼트 레지스터
  • GS 글로벌 세그먼트 등록

이 새로운 세그먼트 레지스터는 프로세서가 강제로 사용하지 않고 프로그래머가 원했던 용도로만 사용할 수있었습니다.

어떤 이들은 이름이 단순히 기존 세트의 C , D , E 테마를 계속하기로 선택되었다고 말합니다 ...

64 비트 레지스터

AMD는 호환 가능하지만 경쟁 버전을 만들기 위해 Intel에서 80386의 디자인을 라이센스 한 프로세서 제조업체입니다. 디자인에 대한 내부적 인 변경을 수행하여 처리량을 개선하거나 디자인에 대한 다른 개선 사항을 적용하면서도 동일한 프로그램을 실행할 수있었습니다.

인텔과의 협력을 통해 인텔 32 비트 디자인을 64 비트 확장하고 32 비트 x86 코드를 실행할 수있는 최초의 64 비트 칩을 생산했습니다. 인텔은 64 비트 아키텍처 버전에서 AMD의 디자인을 따라 잡았습니다.

64 비트 디자인은 여전히 ​​이전 버전과 호환되는 반면 레지스터 세트를 여러 가지로 변경했습니다.

  • 기존의 범용 레지스터는 64 비트로 확장되었으며 R 접두사 인 RAX , RBX , RCX , RDX , RSI , RDI , RBPRSP 명명되었습니다.

    다시 말하지만,이 레지스터의 아래쪽 반은 이전과 같은 E 프리픽스 레지스터 였고, 위쪽 반쪽은 독립적으로 액세스 할 수 없었습니다.

  • R8 , R9 , R10 , R11 , R12 , R13 , R14R15 는 더 많은 64 비트 레지스터가 추가되고 이름이 지정되지 않고 번호가 매겨졌습니다.
    • 이들 레지스터는 32 비트 절반은 낮은 R8D 통해 R15D (평소 DWORD 용 D).
    • 이 레지스터의 하위 16 비트는 레지스터 이름에 WR8W 에서 R15W 까지 액세스 할 수 있습니다.
  • 모든 16 개의 레지스터 중 가장 낮은 8 비트가 이제 액세스 될 수 있습니다 :
    • 전통적인 AL , BL , CLDL ;
    • (전통적으로) 포인터 레지스터의 하위 바이트 : SIL , DIL , BPLSPL ;
    • 그리고 8 개의 새로운 레지스터의 하위 바이트 : R8B 에서 R15B .
    • 그러나 AH , BH , CHDH 는 REX 접두사를 사용하는 명령어 (64 비트 피연산자 크기 또는 R8-R15 액세스 또는 SIL , DIL , BPL 또는 SPL 액세스)에서 액세스 할 수 없습니다. REX 접두사를 사용하면 대신 AH 를 의미하는 기계 코드 비트 패턴은 SPL 등을 의미합니다. 인텔의 지침 참조 설명서 (볼륨 2)의 표 3-1을 참조하십시오.

32 비트 레지스터에 쓰는 것은 8 비트 또는 16 비트 레지스터에 쓰는 것과는 달리 전체 너비 레지스터의 상위 32 비트를 항상 0으로 만듭니다 (이전 값과 병합 됨, 이는 순서가 잘못된 실행에 대한 추가 종속성입니다) ).

플래그 등록

x86 산술 논리 단위 (ALU)가 NOTADD 와 같은 연산을 수행하면 특수 16 비트 FLAGS 레지스터에서 이러한 연산의 결과에 플래그를 지정합니다 ( "0", "오버플로", "음수가되었습니다"). 32 비트 프로세서는이를 32 비트로 업그레이드하여 EFLAGS 라고 불렀지 만 64 비트 프로세서는이를 64 비트로 업그레이드하여 RFLAGS 라고 불렀습니다.

조건 코드

그러나 이름에 관계없이 등록부는 직접 액세스 할 수 없습니다 (몇 가지 지침 제외 - 아래 참조). 대신 JccSETcc 라고하는 Jcc 또는 조건부 집합과 같은 특정 지침에서 개별 플래그가 참조됩니다. 여기서 cc 는 "조건 코드"를 의미하며 다음 표를 참조합니다.

조건 코드 이름 정의
E , Z 평등, 제로 ZF == 1
NE , NZ 평등하지 않고 0이 아닙니다. ZF == 0
O 과다 OF == 1
NO 오버플로 없음 OF == 0
S 서명 됨 SF == 1
NS 서명되지 않음 SF == 0
P 둥가 PF == 1
NP 패리티 없음 PF == 0
-------------- ---- ----------
C , B , NAE 따라 가기, 위에 있지 않거나 같음 CF == 1
NC , NB , AE 나르 지 않거나, 아래 또는 같지 않음 CF == 0
A , NBE 위, 아래 또는 같지 않음 CF == 0 및 ZF == 0
NA , BE 위, 아래 또는 같지 않음 CF == 1 또는 ZF == 1
--------------- ---- ----------
GE , NL 보다 크거나 같음, 덜 나아지지 않음 SF == OF
NGE , L 크거나 같지 않음, 덜 SF ! = OF
G , NLE 크거나 작거나 같지 않음 ZF == 0이고 SF == OF
NG , LE 크거나 작거나 같음 ZF == 1 또는 SF ! = OF

16 비트에서 0 에서 1 을 빼는 것은 부호없는 또는 부호가있는 산술이 사용되는지 여부에 따라 65,535 또는 -1 이지만 대상은 0xFFFF 어느 방향 으로든 보유합니다. 의미가 명확하다는 조건 코드 만 해석하면됩니다. 경우 더욱 말하고 1 에서 제외되기 0x8000 : 부호없는 산술에서, 즉 단순히 변경 32,76832,767 ; 서명 연산에있는 동안은 변경 -32,76832,767 훨씬 더 주목할만한 오버 플로우 -!

조건 코드는 테이블에서 세 가지 블록으로 그룹화됩니다 (부호없는 페이지, 서명되지 않은 페이지 및 서명 된 페이지). 후자의 두 블록 내의 이름은 서명되지 않은 경우에는 "Above"와 "Below"를 사용하고 서명 된 경우에는 "Greater"또는 "Less"를 사용합니다. 따라서 JB 는 "뛰어 오르는 경우"(서명되지 않음)이고, JL 은 "작아 진다면"(서명 된) 것입니다.

FLAGS 직접 액세스하기

위의 조건 코드는 사전 정의 된 개념을 해석하는 데 유용하지만 실제 플래그 비트는 다음 두 가지 명령어로 직접 사용할 수도 있습니다.

  • LAHF AH 레지스터에 플래그를로드합니다.
  • SAHF AH 레지스터를 플래그에 저장

이 명령어로 특정 플래그 만 복사됩니다. 전체 FLAGS / EFLAGS / RFLAGS 레지스터는 스택에 저장하거나 복원 할 수 있습니다.

  • PUSHF / POPF 스택에 / 스택에서 16 비트 FLAGS 푸시 / 팝
  • PUSHFD / POPFD 스택에 /에서 32 비트 EFLAGS 푸시 / 팝
  • PUSHFQ / POPFQ 푸쉬 / 팝 64 비트 RFLAGS 스택에서 상 /

인터럽트는 현재 [R/E]FLAGS 레지스터를 자동으로 저장 및 복원합니다.

기타 플래그

위에서 설명한 ALU 플래그뿐만 아니라 FLAGS 레지스터는 다른 시스템 상태 플래그를 정의합니다.

  • IF 인터럽트 플래그.
    인터럽트를 전역 적으로 활성화하는 STI 명령어로 설정되며 인터럽트를 전역 적으로 비활성화하는 CLI 명령어로 해제됩니다.
  • DF 방향 플래그.
    CMPSMOVS 와 같은 메모리 - 메모리 연산 (메모리 위치를 비교하고 이동)은 명령어의 일부로 인덱스 레지스터를 자동으로 증가 또는 감소시킵니다. DF 플래그는 어느 것이 발생하는지 지시합니다 : CLD 명령으로 지워지면 증가합니다. STD 명령어로 설정하면 감소합니다.
  • TF 트랩 플래그. 이것은 디버그 플래그입니다. 이것을 설정하면 프로세서가 "single-step"모드가됩니다. 각 명령어가 실행 된 후 디버거에서 처리 할 것으로 예상되는 "Single Step Interrupt Handler"를 호출합니다. 이 플래그를 설정하거나 지우는 방법은 없습니다 : 메모리에있는 동안 비트를 조작해야합니다.

80286 플래그

인텔은 80286의 새로운 멀티 태스킹 기능을 지원하기 위해 FLAGS 레지스터에 플래그를 추가했습니다.

  • IOPL I / O 특권 레벨.
    멀티 태스킹 코드를 보호하기 위해 일부 작업에서는 I / O 포트에 액세스 할 수있는 권한이 필요했지만 일부 작업에는 I / O 포트 액세스가 중지되어야했습니다. 인텔은 4 수준의 권한 등급을 도입했으며 00 2 는 권한이 가장 높고 11 2 는 가장 적은 권한을가집니다. IOPL 이 현재 권한 수준보다 낮 으면 I / O 포트에 액세스하거나 인터럽트를 활성화 또는 비활성화하려는 시도는 대신 일반 보호 오류를 발생시킵니다.
  • NT 중첩 작업 플래그.
    이 플래그는 한 태스크가 다른 태스크를 CALL 하여 컨텍스트 전환을 유발 한 경우에 설정되었습니다. 설정 플래그는 RET 가 실행될 때 컨텍스트 전환을 다시 수행하도록 프로세서에 지시합니다.

80386 플래그

'386은 프로세서에 설계된 추가 기능을 지원하기 위해 여분의 플래그가 필요했습니다.

  • RF 이력서 플래그.
    `386은 특정 메모리 위치의 읽기, 쓰기 또는 실행과 같은 다양한 하드웨어 액세스에서 디버거를 호출 할 수있는 디버그 레지스터를 추가했습니다. 그러나 디버그 처리기가 명령을 실행하기 위해 반환 되면 액세스가 즉시 디버그 처리기를 다시 호출합니다! 또는 디버그 핸들러에 진입 할 때 자동으로 설정되고 모든 명령어가 실행될 때마다 자동으로 지워지는 재개 플래그가 아닌 경우 적어도 발생합니다. Resume 플래그가 설정되어 있으면 Debug 핸들러가 호출되지 않습니다.
  • VM 가상 8086 플래그.
    새로운 32 비트 코드뿐만 아니라 더 오래된 16 비트 코드를 지원하기 위해 80386은 가상 8086 집행부의 도움을 받아 "가상 8086"모드에서 16 비트 작업을 실행할 수 있습니다. VM 플래그가이 작업이 가상 8086 작업임을 나타냅니다.

80486 플래그

인텔 아키텍처가 개선됨에 따라 캐시 및 슈퍼 스칼라 실행과 같은 기술을 통해 빨라졌습니다. 그것은 가정을함으로써 시스템에 대한 액세스를 최적화해야했습니다. 이러한 가정을 제어하기 위해 더 많은 플래그가 필요했습니다.

  • AC 정렬 검사 플래그 x86 아키텍처는 크기가 조정되어야하는 아키텍처 (4 바이트 값이 4 바이트 경계에 있어야 함)와 달리 모든 바이트 경계에서 멀티 바이트 메모리 값에 항상 액세스 할 수 있습니다. 그러나 정렬되지 않은 데이터에 액세스하려면 여러 메모리 액세스가 필요했기 때문에 그렇게하는 것이 덜 효율적이었습니다. AC 플래그가 설정된 경우 정렬되지 않은 액세스는 코드를 실행하지 않고 예외를 발생시킵니다. 이렇게하면 AC 세트로 개발하는 동안 코드를 향상시킬 수 있지만 프로덕션 코드에서는 사용할 수 없습니다.

펜티엄 플래그

펜티엄은 가상화에 대한 추가 지원과 CPUID 명령 지원을 추가했습니다.

  • VIF 가상 인터럽트 플래그.
    이것은이 작업의 IF 의 가상 복사본입니다.이 작업이 인터럽트를 사용하지 않도록 설정했는지 여부는 실제로 전역 인터럽트에 영향을 미치지 않습니다.
  • VIP 가상 인터럽트 보류 플래그.
    이는 인터럽트가 VIF 에 의해 사실상 차단되었으므로 태스크가 STI 수행 할 때 가상 인터럽트를 발생시킬 수 있음을 나타냅니다.
  • ID CPUID 허용 된 플래그.
    이 태스크가 CPUID 명령을 실행할 수 있도록 허용할지 여부. 가상 모니터는이를 허용하지 않을 수도 있고 명령을 실행하는 경우 요청한 태스크에 "거짓말"할 수도 있습니다.


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow