1. x86 아키텍쳐 cpu 레지스터
C언어 register 키워드
1 |
|
- 변수를 선언할 때 register로 선언을 하면 메모리 대신 CPU 레지스터 사용
- 일반 변수보다 속도 빠름
- 레지스터 개수 한정 => register를 붙인다고 해서 모두 레지스터 사용X
- CPU 레지스터를 사용하므로 메모리에 생성 안됨 => &연산자 사용 불가
- 레지스터 변수에 주소값 저장하면 * 연산자는 사용 가능
- 지역 변수에만 사용 가능
범용 레지스터
- AX (Accumulator register) : 산술 연산에 사용
- CX (Counter register) : 시프트/회전 연산과 루프에서 사용
- DX (Data register) : 산술 연산과 I/O 명령에서 사용
- BX (Base register) : 데이터의 주소를 가리키는 포인터로 사용 (세그멘티드 모드에서는 세그멘트 레지스터 DS로 존재)
- SP (Stack Pointer register) : 스택의 최상단을 가리키는 포인터로 사용
- BP (Stack Base Pointer register) : 스택의 베이스를 가리키는 포인터로 사용
- SI (Source Index register) : 스트림 명령에서 소스를 가리키는 포인터로 사용
- DI (Destination Index register) : 스트림 명령에서 도착점을 가리키는 포인터로 사용
비트 별 범용 레지스터 이름
Accumulator | Counter | Data | Base | Stack Pointer | Stack Base Pointer | Source | Destination | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
64-Bit | RAX | RCX | RDX | RBX | RSP | RBP | RSI | RDI | ||||||||
32-Bit | EAX | ECX | EDX | EBX | ESP | EBP | ESI | EDI | ||||||||
16-Bit | AX | CX | DX | BX | SP | BP | SI | DI | ||||||||
8-Bit | AH | AL | CH | CL | DH | DL | BH | BL |
세그먼트 레지스터
- SS (Stack Segment) : 스택 영역의 시작 주소
- CS (Code Segment) : 코드 영역의 시작 주소
- DS (Data Segment) : 데이터 영역의 시작 주소
- ES (Extra Segment) : 다른 데이터의 주소(E는 Extra와 동치)
- FS (F Segment) : 또 다른 데이터의 주소(F는 E 뒤에 있다)
- GS (G Segment) : 또 다른 데이터의 주소(G는 F 뒤에 있다)
2. 스택 프레임과 함수 프롤로그, 에필로그
스택 프레임
함수가 호출되면 스택 영역에는
- 함수의 매개변수
- 호출이 끝난 뒤 돌아갈 반환 주소값
- 함수에서 선언된 지역변수
등이 저장된다.
이렇게 스택 영역에 차례대로 저장되는 함수의 호출 정보를 스택 프레임이라 한다.
1 |
|
위 코드에서의 함수 호출에 의한 스택 프레임의 변화는 아래 그림과 같다.
함수의 호출 과정
- 함수가 사용할 매개변수를 스택에 넣고 함수 시작 지점으로 점프
- 함수 내에서 사용할 스택 프레임 설정 (프롤로그)
- 함수 내용 수행
- 수행을 마치고 처음 호출한 지점으로 돌아가기 위해 스택 복원 (에필로그)
함수 프롤로그
프롤로그는 함수 내에서 사용할 스택 프레임을 설정하는 과정이다.
1 |
|
베이스 포인터를 스택에 저장하고, 현재 스택 포인터를 베이스 포인터에 저장
함수 에필로그
에필로그는 함수 수행을 마치고 처음 호출한 지점으로 돌아가기 위해 스택을 복원하는 과정이다.
1 |
|
스택 포인터를 베이스 포인터로 복구한 후, 베이스 포인터를 복구해주고 ret
3. 함수의 호출 규약
__cdecl 방식
- C/C++함수에서 기본적으로 사용되는 호출 규약
- 인자는 오른쪽에서 왼쪽으로 전달
- 호출자가 스택 프레임 정리
- 가변 인자 함수 생성 가능
__stdcall 방식
- Win32 API에서 사용
- 인자는 오른쪽에서 왼쪽으로 전달
- 피호출자가 스택 프레임 정리
- 매개 변수 개수 고정
__fastcall 방식
- 스택이 아닌 가까운 레지스터 사용
4. CPU Cashing
대부분의 메모리 접근은 특정한 위치 주변에서 자주 일어나는 경향이 있기 때문에 속도가 매우 빠른 캐시메모리에 복사해두면 평균 메모리 접근 시간을 단축 시킬 수 있다.
사용처
- 배열 전체의 합을 구해서 한 변수에 저장할 때
- http://icpc.me/1182 처럼 데이터의 수는 작으면서 여러 번 접근해야 하는 NP문제를 풀 때