IA-32

X86 아키텍처 **IA-32**(Intel Architecture, 32-bit) 또는 **x86-32**는 인텔의 32비트 마이크로프로세서에서 사용하는 명령 집합 아키텍처이며, 이전에 사용되던 IA-16 아키텍처의 32비트 확장이다. IA-32를 x86이라는 이름으로 부르기도 하지만 엄밀하게는 x86 아키텍처는 IA-16, IA-32, x86-64 등을 모두 포함하는 일반적인 이름이다. IA-32는 인텔 마이크로프로세서 아키텍처 중 가장 성공적이었으며 대부분의 개인용 컴퓨터에서 사용되고 있다. PowerPC 등의 아키텍처들이 IA-32를 대체하려 시도했으나 아직까지 비교될 정도의 시장 점유율은 확보하지 못 했다. 인텔 프로세서들의 성공에 힘입어 다른 많은 프로세서들에서도 IA-32를 지원하고 있으며 그중 가장 유명한 곳은 AMD이다. IA-32 명령 집합은 1985년에 발표된 인텔 80386에서 처음 등장했으며, 현재에도 계속 사용되고 있다. 시간이 지나면서 명령 실행 속도가 높아졌고 MMX와 같은 확장 명령들이 계속 추가되어 왔으나, 이전에 지원되던 명령들이 사라지는 경우는 거의 없어 상위 호환성은 유지되었다. IA-32 아키텍처는 보통 CISC 아키텍처의 대표적인 예로 제시되곤 하지만, 마이크로프로세서 디자인의 진보로 이런 구분이 큰 의미를 갖지는 않는다. 현재 대부분의 x86 아키텍처들(예를 들면, K7과 NetBurst 혹은 그 이후)은 "후기 RISC 프로세서"로 종종 언급되곤 한다. 인텔은 IA-32 프로세서의 개발사이며 최대의 공급자이다. 그러나 단순 공급에만 그치지만은 않는다. IA-32의 두 번째 큰 공급자는 AMD이다. 그 이외의 다른 공급자들도 있긴하나 비중이 크지는 않다. 2007년 이후로 인텔은 x86-64 아키텍처로 무게중심을 옮기고 있다. 하지만, 여전히 노트북용 셀러론 M과 같은 IA-32 프로세서들을 생산하고 있다. VIA Technologies는 VIA C3와 C7계열의 "순수" IA-32장치들을 계속해서 생산하고 있다. 또한 AMD 역시 Geode 계열과 이동형 IA-32 프로세서들을 아직도 생산하고 있다. 한때 Transmeta는 IA-32프로세서(Crusoe)를 생산한 적이 있었다.
# 메모리 관리 모델
IA-32가 지원하는 메모리 관리 모델은 두 가지로, 1MB의 메모리만을 접근할 수 있는 실제 모드(real mode)와 전체 메모리를 접근할 수 있는 보호 모드(protected mode)가 있다.
## 실제 모드
**실제 모드**(real mode)는 처음 부팅했을 때 기본으로 활성화되는 모드이다. 옛 도스의 경우 이 모드를 사용했지만, 마이크로소프트 윈도우와 리눅스를 비롯한 최근의 운영 체제들은 거의 대부분 보호 모드를 사용하기 때문에 부팅될 때 보호 모드로 전환하는 명령을 사용한다.
## 보호 모드
**보호 모드**(protected mode)는 1MB 이상의 메모리를 지원할 뿐만 아니라 다양한 장점을 가지고 있다. 보호 모드의 가장 큰 장점은 멀티태스킹을 지원하고 이를 위해 가상 메모리와 메모리 접근 권한을 지원한다는 것이며, 따라서 최근의 거의 모든 운영 체제는 보호 모드를 사용한다. 주소가 32비트이기 때문에 보호 모드에서 사용할 수 있는 메모리는 보통 4GB로 제한되어 있지만, 64비트 아키텍처로 전환하지 않고도 4GB 이상의 메모리를 접근할 수 있는 방법이 몇 가지 있다. 그중 하나로 가상 메모리의 페이지 테이블을 확장하여 64GB까지를 사용할 수 있는 물리 주소 확장(Physical Address Extension)이 있다. 보호 모드는 가상 8086 모드(virtual 8086 mode)라 하여, 옛 도스 프로그램과 운영 체제를 보호 모드의 운영 체제의 통제 아래서 실행할 수 있는 특수한 모드를 제공한다. 이 모드는 IA-16의 보호 모드에서는 지원하지 않던 것으로 IA-32에서 추가된 것이다.
# 레지스터
처음에 인텔 80386은 32비트 일반 레지스터 8개와 부동소수점 실수 레지스터 8개를 지원했다. 뒤에 나온 프로세서들은 MMX (명령어 집합), 3DNow!, SSE, SSE2, SSE3과 같은 다양한 SIMD 명령 집합들을 위한 레지스터들을 더 지원한다. 또한, 응용 프로그램에 의해 사용되지는 않고 운영 체제에 의해 빈번하게 사용되는 시스템 레지스터들이 존재한다. segment, control, debug 그리고 test 레지스터가 그들이다. 여섯개의 segment 레지스터는 주로 메모리 관리에 사용되며, control, debug, test 레지스터는 모델에 따라 다양하다.
## 범용 레지스터
엄밀히 말하면 x86 아키텍처의 범용 레지스터는 이름과는 다르게 일부 특수한 기능을 가지고 있다. 이들 범용 레지스터들은 보통 자유롭게 대입이나 연산이 가능하긴 하지만 특정 명령에서는 하나 또는 두 개의 레지스터만을 쓸 수 있는 경우가 상당수 존재하며, 데이터를 다루는 레지스터와 주소를 다루는 레지스터가 서로 분리되어 있다. 또한 많은 수의 명령들이 레지스터에 메모리의 내용을 따로 옮기지 않고도 연산을 수행할 수 있다. 이런 특이한 구현은 1970년대의 관습에서 이어진 것으로, 후대의 아키텍처들과 IA-32 확장(예를 들어 AMD64의 64비트 확장)에서는 모든 범용 레지스터는 모든 명령에서 사용할 수 있도록 되어 있다. 물론 이는 IA-32에 영향을 끼치지는 않았다.
### 일반 레지스터
32비트 일반 레지스터는 4개가 있다. 이들은 주소 레지스터보다는 더 일반적인 용도로 쓰이지만, 특정 명령에서는 특정한 레지스터만 쓸 수 있는 경우가 있다. * EAX: 누산기에 해당하며 대부분의 연산들이 수행된다. 일반적으로 프로시저의 return 값을 저장한다. * ECX: 개수, 횟수 등을 저장하는 카운터로 주로 사용된다. * EDX: 누산기의 확장으로 누산기와 관련된 연산에서 사용된다. EDX와 EAX를 합쳐 64비트 연산을 하는 경우가 대표적이다. * EBX: 일반적인 데이터 레지스터로, 원래 16비트 모드에서는 포인터로 사용했다.
### 8비트 및 16비트 레지스터
8비트 및 16비트의 레지스터도 역시 사용이 가능하다 예를 들어 32비트 EAX 레지스터의 하위 16비트는 AX 레지스터라는 이름으로 접근이 가능하다. 16비트 레지스터 중 일부는 32비트 레지스터의 경우와 마찬가지로 하위의 8비트로 분할할 수 있다. 16비트 레지스터의 상위 8비트를 AH 레지스터라고 불리며 하위 8비트를 AL레지스터라고 한다. 이와 유사하게 EBX 레지스터도 BX(16비트), BH(상위 8비트)와 BL(하위 8비트로)나뉠 수 있다.
### 주소 레지스터
32비트 일반 주소 레지스터는 4개가 있으며, 일반 레지스터에 속하지 않는 주소 레지스터 EIP도 있다. * ESP (stack pointer): 스택의 꼭대기 주소를 담는다. * EBP (base pointer): 현재 스택 프레임의 주소를 담으며, 일반적인 목적으로 쓰기도 한다. * ESI (source index): 문자열 연산에서 사용되는 원본 주소를 담는다. * EDI (destination index): 문자열 연산에서 사용되는 목적 주소를 담는다. * EIP (instruction pointer): 다음에 실행될 명령의 주소를 담는다. 프로그램 카운터와 같은 역할이다.
## 부동소수점 레지스터
IA-32는 원래 8087, 80287, 80387 같은 별도의 프로세서로 부동소수점 연산을 지원했다. 80486 이후로 부동소수점 연산이 프로세서에 통합되었으며 ST(0)부터 ST(7)까지의 8개의 부동소수점 레지스터도 일반적으로 사용 가능하게 되었다. 이 레지스터들은 80비트이며 IEEE 754의 확장 배정밀도 형식을 사용한다. 부동소수점 레지스터는 직접 접근할 수 없으며 스택을 사용하여 접근한다. 레지스터 번호는 고정되어 있지 않으며 스택 꼭대기에 상대적이다. 즉 ST(0)은 스택 꼭대기에 있는 값이고, ST(1)은 그 아래에 있는 값이다. 모든 부동소수점 연산은 스택에서 몇 개의 값을 꺼내서 연산한 뒤 다시 스택에 집어 넣는 방식으로 이루어진다. IA-32의 확장인 MMX (명령어 집합)와 3DNow!에서는 부동소수점 레지스터를 다른 용도로 사용한다. 따라서 이들 기능과 부동소수점 연산을 동시에 수행할 수 없다는 단점이 있지만 한편으로는 별도의 레지스터를 추가하지 않으므로 레지스터 상태 등을 저장해야 하는 경우 이전과 같은 방법을 사용할 수 있다는 장점이 있다.
### MMX 레지스터
MMX 확장에서는 MM0부터 MM7까지 8개의 레지스터가 추가되었다. 실제로 MMX 레지스터는 이미 존재하던 부동소수점 레지스터들의 하위 비트들과 동일하며, 스택을 사용하지 않으므로 레지스터 번호가 상대적이지 않다는 차이점만 있다. MMX 레지스터는 64비트지만, 하나의 레지스터를 명령에 따라 각각 8비트, 16비트, 32비트, 64비트씩 해석하는 압축 자료형(packed data type)을 제공한다. MMX 레지스터와 부동소수점 레지스터가 실제로는 동일하기 때문에 둘을 함께 사용할 수는 없다. MMX 레지스터가 사용될 경우 상위 16비트는 모두 1로 채워지며, 이는 부동소수점 형식으로는 NaN 또는 무한대로 해석되기 때문에 현재 처리하는 데이터가 부동소수점 데이터인지 MMX 데이터인지 판단하기 쉬워진다.
### 3DNow! 레지스터
3DNow! 확장은 MMX를 정수에서 부동소수점 실수로 확장한 것이다. 이 확장에서는 MMX와 똑같이 MM0부터 MM7까지의 64비트 레지스터를 사용하며, 단지 64비트 레지스터를 두 개의 32비트 단정밀도 부동소수점 형식으로 취급하는 것만 다르다.
## SSE 레지스터
MMX와 3DNow!는 부동소수점 레지스터를 공유했기 때문에 크기에 제한이 있었다. SSE 확장은 부동소수점 레지스터를 더 이상 사용하지 않고, XMM0부터 XMM7까지의 128비트 레지스터 8개를 새로 추가했다. (AMD64에서는 XMM0부터 XMM15까지 16개의 레지스터를 지원한다.) SSE 확장이 등장하면서 인텔은 새 레지스터들의 상태를 저장하기 위한 명령들을 함께 추가했으며, 호환성을 위해 보호 모드와 같지만 SSE 관련 명령을 지원하는 강화 모드(enhanced mode)도 만들었다. SSE는 3DNow!와 같이 부동 소숫점을 다루는 확장이지만 레지스터 크기가 두 배기 때문에 단정밀도(32비트) 부동소수점 실수 4개를 한꺼번에 다룰 수 있다. 원래 SSE는 배정밀도(64비트) 부동소수점 실수를 다룰 수 없었지만 SSE2 확장에서는 배정밀도 부동소수점 실수 두 개를 한꺼번에 다루는 명령들이 추가되었다.
# 64비트 확장
IA-32는 멀티미디어 관련 명령들을 추가하며 발전해 왔지만, 여전히 32비트 환경만을 지원한다. IA-32를 64비트 환경에서 쓸 수 있도록 한 확장으로는 인텔의 IA-64와 AMD의 AMD64가 있으며, 마이크로소프트는 업체 중립적인 IA-32의 64비트 확장의 이름으로 x64를 제안해서 사용하고 있다.
## IA-64
인텔의 IA-64 아키텍처는 이름은 유사하지만 IA-32와 호환되지 않는 완전히 새로운 아키텍처로, 아이테니엄 계열 프로세서에서 사용되고 있다. IA-64는 비순차적 실행(out-of-order execution) 대신 VLIW 디자인을 채용하였다. 아이테니엄은 IA-32를 하드웨어적으로 지원하기는 하지만, IA-64와 IA-32간의 명령어가 호환되지 않기 때문에 상당히 느린 속도로 구현된다. 2006년 기준으로 VLIW 아키텍처는 컴파일러의 지원이 부족하여 개발이 어렵다는 평가를 받는다. 한 예로 GCC 컴파일러의 중간언어인 RTL은 VLIW에서 매우 느리다.
## AMD64
AMD의 AMD64(또는 x86-64) 명령 집합은 IA-32와 대부분 호환되면서 64비트 기반으로 옮겨 간 아키텍처이다. AMD64는 IA-32에서 아직까지 지원하고 있는 16비트 지원들을 대부분 버렸고, 특히 일반 레지스터들을 어떤 곳에라도 쓸 수 있게 했으며 대부분의 세그먼트 레지스터들을 없앴다. (다만 FS와 GS는 윈도와의 호환을 위해 남겨졌다) 또한 일반 레지스터와 SSE 레지스터의 수가 각각 8개에서 16개로 늘어났다.
## EM64T
2004년 2월에 인텔은 EM64T 명령 집합을 발표했다. EM64T는 AMD64의 구현이며, AMD64와 대부분 호환되지만 몇몇 기능들이 지원되지 않는다. 인텔은 2004년 후반부터 제온 코어에서 이 명령 집합을 사용하기 시작했으며, 데스크톱 시장의 경우 2005년 초부터 펜티엄 4에서 지원하기 시작했다.