X86

소문자 x86 아키텍처 **x86** 또는 **80x86**은 인텔이 개발한 마이크로프로세서 계열을 부르는 말이자, 이들과 호환되는 프로세서들에서 사용한 명령어 집합 구조들을 통칭하는 말이다. x86 아키텍처는 데스크톱 컴퓨터 시장에서 매우 널리 쓰이며, PowerPC 같이 좀 더 근대적인 아키텍처를 사용한 프로세서들이 x86과 경쟁했으나 그다지 많은 시장 점유율을 확보하지는 못했다. x86 또는 80x86이라는 이름은 여기에 속하는 초기의 프로세서들 이름이 모두 80으로 시작해서 86으로 끝났기 때문에 붙여졌다. 여기에는 8086, 80186, 80286, 386, 486이 포함되며 숫자로 상표를 등록할 수 없었기 때문에 그 뒤로는 펜티엄과 같은 별도의 이름을 사용하게 되었다. 그러나 586, 686과 같은 이름은 아직까지도 (비공식적으로) 사용되며, 전체 아키텍처를 나타내는 말에도 그 흔적이 남아 있다. x86 아키텍처를 사용한 최초의 프로세서는 1978년에 발표된 인텔 8086으로, 이전 프로세서인 인텔 8080과 어셈블리어 단에서 호환되도록 설계되었다.Stephen P. Morse(1980),《Intel Microprocessors: 8008 to 8086》인텔 8080의 어셈블리어 코드를 그대로 어셈블하면 x86에서 작동하는 코드가 출력된다는 말이 아니다. 인텔 8086은 3년 후에 IBM PC의 표준 프로세서로 채택되었다. IBM PC는 계속 성장하여 개인용 컴퓨터 업계의 표준이 되었으며, 그에 따라 x86 아키텍처는 매우 성공적인 명령 집합 아키텍처가 되었다. 사이릭스, 닛폰 전기(NEC), IBM, 트랜스메타 등의 회사들이 x86 아키텍처를 사용하는 프로세서를 생산했으며, 그중 AMD의 애슬론 계열 프로세서들은 펜티엄에 미치지는 못 하지만 상당한 시장 점유율을 차지하고 있다. x86 아키텍처는 variable-length code의 CISC 설계를 채용했으며, 하위 호환성에 중점을 두고 있다. x86 아키텍처는 다른 아키텍처와 같이 워드 경계에 맞춰서 메모리를 읽는 것이 효율적이긴 하지만, 워드 경계에 걸치는 메모리도 한 번에 접근할 수 있다. 워드들은 최하위 바이트부터 최상위 바이트까지 순서대로 (리틀 엔디안) 저장된다. 현재의 x86 프로세서들은 명령들을 내부적으로 더 작은 단위로 쪼개서 RISC와 비슷한 내부 아키텍처에서 수행한다.
# IA-16 (Intel Architecture, 16-bit)
인텔 8086과 8088은 14개의 16비트 레지스터를 지원했다. 네 개(AX, BX, CX, DX)는 일반 레지스터로, 실제로는 명령에 따라서 특수하게 쓰인다. (예를 들어 LOOP 명령은 항상 CX 레지스터를 사용한다.) 일반 레지스터는 상위 8비트(AH, BH, CH, DH)와 하위 8비트(AL, BL, CL, DL)를 따로 접근할 수도 있다. 네 개의 세그먼트 레지스터(CS, DS, SS, ES)는 메모리 주소의 기준을 정하는 데 사용하며, 두 개의 포인터 레지스터(SP, BP)는 메모리 주소를 담는 데 쓰인다. 두 개의 레지스터(SI, DI)는 배열을 참조하는 데 쓰이고, FLAGS 레지스터는 자리올림, 오버플로 등의 상태 비트를 담고 있으며, 마지막으로 IP 레지스터는 현재 세그먼트에서 다음에 실행될 명령어의 offset을 저장한다. 당시 8086은 64 KiB(65,536 바이트)의 메모리 공간과 64 KiB의 스택 공간을 지원했다. 스택에는 한 워드 단위로 값을 넣거나 뺄 수 있으며, 스택의 꼭대기는 SS:SP에 저장된다. 스택에 값을 넣으면 SS:SP는 줄어들며, 따라서 스택의 꼭대기는 실제로는 전체 스택에서 가장 주소가 작은 곳에 있다. 256개의 하드웨어 및 소프트웨어 인터럽트가 지원되며, 반환 주소를 스택에 저장하기 때문에 한 인터럽트가 처리되는 도중에 다른 인터럽트가 걸릴 수도 있었다.
## 실제 모드
인텔 80286부터는 **실제 모드**(real mode)라는 프로세서 모드가 부팅시 기본으로 활성화되었다. 실제 모드는 20비트의 주소를 사용할 수 있으며, 따라서 1MiB의 메모리를 접근할 수 있다. 또한 바이오스 루틴과 주변 장치를 소프트웨어적으로 직접 접근할 수 있으나 멀티태스킹과 같은 개념을 하드웨어적으로 지원하지는 않는다. 실제 모드에서는 메모리를 접근할 때 해당하는 16비트 세그먼트와 실제로 사용되는 16비트 주소를 합쳐서 20비트 주소를 만드는데, 예를 들어 DS가 A000h이고 SI가 5677h이면 DS:SI는 DS × 16 + SI = A5677h라는 주소를 가리키게 된다. 메모리 접근에 사용할 수 있는 세그먼트는 네 개(CS, DS, ES, SS) 있으며, 그중 CS와 SS는 프로그램 실행에 밀접한 연관이 있기 때문에 실제로는 DS와 ES만을 사용했다. 실제 모드는 프로그래밍과 컴파일러 설계를 어렵게 했는데, 현재 세그먼트 안에서 접근할 수 있는가 없는가를 검사해서 다른 명령을 만들어야 했기 때문이다. 이때 세그먼트 안에서 접근할 수 있는 포인터를 가까운 포인터(near pointer)라 하고, 그렇지 않으면 먼 포인터(far pointer)라 한다. 이런 종류의 전환 과정은 그 뒤의 아키텍처에서도 종종 나타나는데 (예를 들어 MMX (명령어 집합)의 EEMS 명령) 결과적으로 프로그래밍을 더 어렵게 했다.
## 보호 모드
인텔 80286은 실제 모드 외에도 **보호 모드**(protected mode)라는 별도의 모드를 하나 더 제공했다. 이 모드에서는 16 MiB의 물리 메모리와 1 GiB의 가상 메모리를 접근할 수 있으며, 세그먼트 레지스터를 별도의 세그먼트 테이블에 있는 기준 주소를 가리키도록 하였다. 이러한 테이블은 전역 기술 테이블(GDT)과 지역 기술 테이블(LDT)의 두 개로 나뉘는데, 각각 8192개의 24비트짜리 세그먼트 기술자를 담고 있으며 한 세그먼트는 64 KiB의 메모리를 담고 있다. 각 세그먼트 별로 네 개의 보호 단계(ring) 중 하나가 부여되며, 이를 통해 해당 세그먼트에서 실행되는 코드의 권한을 설정할 수 있다. OS/2와 같은 운영 체제는 실제 모드와 보호 모드를 전환하면서 함께 쓰려는 시도를 했으나, 느릴 뿐만 아니라 실제 모드의 프로그램이 자주 컴퓨터를 중단시켰기 때문에 안전하지도 않았다. 윈도우 3.0에서는 실제 모드에서 만들어진 프로그램을 보호 모드에서 돌려야 했는데, 이는 윈도우 3.0이 소프트웨어적으로 가상 메모리를 구현했으며, 따라서 실제 모드에서 절대 주소를 접근하면 위험했기 때문이다. 윈도우 3.1에서는 실제 모드를 사용하지 않는다.
# IA-32 (Intel Architecture, 32-bit)
IA-32 인텔 80386은 이전 아키텍처를 32비트 환경으로 확장했다. 모든 레지스터와 명령, I/O 공간 및 메모리는 32비트로 확장되었으며, 보호 모드 역시 32비트 보호 모드로 확장되었다. 보호 모드에서 각각의 프로그램은 4 GiB의 메모리를 접근할 수 있으며, 페이징을 지원하기 때문에 가상 메모리를 하드웨어적으로 구현할 수 있다. 예외적으로 인텔 80386SX는 비용 절감을 위해 24비트 주소와 16비트 데이터 버스를 사용한다. 새로운 일반 레지스터가 추가되지는 않았으나, 모든 16비트 레지스터는 32비트로 확장되었다. 확장된 32비트 레지스터는 원래 16비트 레지스터 이름 앞에 ‘E’를 붙여서 EAX, ESI 등의 이름을 사용한다. 명령 집합은 하위 호환성을 위해 16비트와 32비트 명령을 서로 전환할 수 있도록 고쳐졌고, 명령 앞에 특수한 접두어를 붙여서 16비트 상태에서 32비트 명령을 쓰거나 32비트 상태에서 16비트 명령을 사용할 수도 있다. 인텔 80386은 세그먼트 메모리 모델과 페이징을 지원한 첫 프로세서였으며, 이 기능들은 멀티태스킹 운영 체제에 필수적이었다. 리눅스, 386BSD, 윈도우 NT 등이 386 이상의 프로세서를 대상으로 개발되었고, 그 이후로 386 아키텍처는 x86 아키텍처의 기반이 되었다. 인텔 80486에서는 기존의 인텔 80387 같은 코프로세서가 부동소수점 장치(FPU)로 통합되었다. 예외적으로 인텔 80486SX는 비용 절감을 위해 FPU를 지원하지 않았다.
## SIMD 명령 집합
80486 이후 x86 아키텍처에는 멀티미디어 처리를 위한 SIMD 명령 집합과 이를 위한 레지스터들이 추가되었다. 이 중 처음으로 도입된 것은 펜티엄 MMX에서 소개된 **MMX**로, 부동소수점 레지스터와 공유되는 64비트 정수 레지스터 8개(MM0부터 MM7까지)와 이들을 다루는 명령들이 추가되었다. 또한 중앙처리장치의 벡터 처리가 중요해지면서 AMD에서는 부동소수점 실수를 처리하기 위한 **3DNow!** 확장을 만들었으며, 새로운 128비트 정수 및 실수 레지스터를 사용하는 **SSE**, **SSE2**, **SSE3** 등의 확장도 등장했다.
# IA-64 (Intel Architecture, 64-bit)
IA-32는 4 GiB의 메모리만 접근할 수 있으며, 따라서 대규모의 처리가 필요한 멀티미디어 작업이나 데이터베이스 등에 한계를 드러냈다. IA-32에서 최대 64 GiB의 메모리를 접근할 수 있게 한 물리 주소 확장(PAE) 등도 등장했지만 근본적인 해결책은 되지 못했다. 이에 따라 IA-32의 64비트 확장이 여럿 제안되었는데, 보통 이들을 통칭하여 x64라 부른다. 대표적으로 완전히 새로운 설계를 사용하며 하위 호환성이 보장되지 않는 인텔의 **IA-64**와, IA-32와 호환되면서 64비트 명령을 추가한 AMD의 **AMD64**(x64)가 있다. IA-64를 사용하는 아이테니엄 계열 프로세서들은 IA-32를 하드웨어적으로 지원하기는 하지만 상당히 느리다. 2004년에 인텔은 AMD64의 구현인 **EM64T**를 발표했으며, 데스크톱 환경에서는 펜티엄 4부터 지원하고 있다.