본문 바로가기
전공/시스템 프로그래밍

[시스템 프로그래밍 3-2] 32 bit register (레지스터) 상세 기능

by 뜨거운 개발자 2023. 3. 20.

기본 실행 환경 개요

  • 컴퓨터의 메모리는 계층 구조를 가지고 있다. - 폰노이만 컴퓨터 구조에서 데이터를 주고 받는게 필수적이기 때문에
  • 메모리 값을 읽어오는데도 시간이 오래 걸리고 (한클럭 만으로 되는게 아니라 최소 4클럭은 소요) cpu에서 일하는데 클럭소요, 메모리로 다시 돌려주는데도 시간이 소요된다.
  • 이렇기 때문에 폰노이만 컴퓨터는 메모리와 cpu간의 데이터를 주고 받는 과정이 필수적이고 그렇기 때문에 cpu에 가까울수록 빠르게 만드는 구조를 선택했다.
    • 따라서 최대한 덜 멀리 이동시키는 방식을 사용한다.
    • 따라서 캐시에 즉 가까운 곳에 저장하는 방식으로 효율성을 높인 것이다.
  • 램에서 쓰는 다이나믹 메모리보다 훨씬 속도가 빠르다. 대신 컨벤셔널 메모리를 사용한다. (캐쉬 레지스터에서 사용 비싸다.)
  • 어셈블리 랭귀지를 직접 프로그래밍을 하면 for 루프 같은 경우 쓸때없이 횟수를 위한 변수를 연산하는 걸 효율적으로 만들 수 있게 된다.
    • IOT같은 곳에서 상당한 힘을 가진다.

32비트 레지스터

8개의 범용 레지스터(32비트) 와 6개의 세그먼트레지스터(16비트), 플래그 레지스터 , 인스트럭터 포인터를 가지고 있다.

각각의 레지스터에 대해 더 자세히 알아보자.

범용 레지스터 (32비트) - 8개 

EAX, EBX, ECX, EDX, EBP, ESP, ESI, EDI 로 총 8개이다.

8개의 범용 레지스터는 일반적인 연산을 할 때 사용되는 레지스터들이다.

32비트 컴퓨터라고 불리는 이유는 32비트 범용 레지스터를 사용하기 때문이다.

역활은 데이터 전송(메모리에서 cpu로 또는 cpu에서 메모리로 보내는 경우) 하는 일을 범용 레지스터가 한다.

또한 주로 산술연산들의 피연산자로 사용이 된다.

결과값이 번용 레지스터에 담긴다.

특징 

  • 주로 산술 및 데이터 이동에 사용됩니다.
  • 그림에서 볼 수 있듯 EAX레지스터는 2개로 잘리는데 하위 16bit는 AX라는 이름으로 참조할 수 있습니다.

네이밍

범용 레지스터는 보면 다 E가 붙어있음을 볼수가 있다. 여기서 E는 Extand를 의미한다.

EAX의 아래쪽에 해당하는 16비트가 AX라고 한다.

또 AX의 절반을 잘라서 앞쪽 8비트를 AH 뒤쪽 8비트를 AL이라고 한다.

이렇게 이상한 네이밍을 사용하는 이유는 다 legacy때문에 그렇다. 이전 버전은 낮은 비트를 사용했기 때문에 호환성 유지를 하기 위한 네이밍이다.

 

이런식으로 EAX, EBX, ECX, EDX는 다 자를 수 있지만, EBP 와 ESP 같은 경우 과거 8비트 체계에서는 없던 것들이라서  BP와 SP는 자를 수가 없다.

8bit 부터 호환성을 유지하는 레지스터 표 

16비트에 없다가 32비트에서 추가된 레지스터 표

범용 레지스터 별로 특별한 기능이 있는데 각 기능을 알아보자.

범용 레지스터별 기능

EAX

  • 곱셈과 나눗셈을 할 때 자동으로 사용이 된다.
  • Mul EBX의 의미는 EAX 의 값과 EBX의 값을 곱하라는 의미이다. (뒤에 뭐가 오더라도 EAX )와의 연산을 의미한다는 뜻.
  • extended accumulator register 라고 불리기도 한다.

ECX

  • 루프에서 숫자를 셀 때 자동으로 cpu가 사용을 한다.(루프카운터)

ESP extended stack pointer register

  • 스택을 가리키는 포인터로 주로 사용이 된다. (스택포인터) - 스택의 데이터 주소 지정
  • 데이터를 전송하거나 산술연산을 할 때는 거의 사용이 안된다고 봐도 무방하다.
  • 스택에 쌓여있는 데이터를 보는 용도.
  • extended stack pointer register 라고 불린다.

ESI and EDI

  • 메모리 전송에 사용이 되는 레지스터들이다.
  • 고속 메모리 전송 명령에 사용이 된다.
  • 메모리에 어떻게 엑세스 할때 사용하는지 볼수 있다.
  • extended source index and extended destination index registers 라고 불린다.

EBP extended frame pointer

  • 하이레벨 언어에서 함수 인자나 지역 변수들이 스택에 올라와있는데 그 녀석들을 참조 하기 위해서 사용이 된다.
  • 고급 수준의 프로그래밍을 제외하고 일반적인 연산이나 데이터 전송에는 사용해서는 안된다.
  • 확장프레임 포인터 레지스터(extended frame pointer register)라고도 한다.

비 범용 레지스터의 종류

1. 세그먼트 레지스터

모드에 따라서 사용법이 다르다. 각 모드별로 살펴보자.

리얼모드

  • 리얼모드에서는 16비트 세그먼트 레지스터는 사전 할당 된 메모리 영역의 기본주소(세그먼트)를 나타낸다.
  • 주소는 20bit이고 레지스터가 16비트라서 주소를 한번에 표현 할 수가 없다.
  • 따라서 이때 사용하는 방식이 층과 호수를 분리하는 느낌으로 이해하면 되는 방식을 사용하였다.
  • 주소를 층과 호수로 분리한 것처럼 2개로 분리하여서 segment라는 개념이 등장하게 되었다.
    • segment는 층수에 해당하고 offset은 호실 수에 해당한다.
    • 이 두가지를 결합해서 주소를 레지스터에서 표현하였다.

이 세그먼트 레지스터는 사실상 층에 해당하고 결국 offset값과 결합이 되어야만 제대로 나타낼 수 있는 레지스터인 것이다.

즉 16비트 세그먼트 레지스터는 base address 를 가리키는 데 그것은 segment라고 부른다.

호수가 offset 이다.

보호모드

레지스터들이 다 32비트이고 메모리 주소도 32비트이다.

따라서 이제는 층과 offset을 나눠서 사용할 필요가 없어졌다.

보호모드에서는 segment register는 세그먼트 디스크립터 태이블의 포인터를 가리키고 있다.

보호모드에서는 메모리를 여러개의 세그먼트로 나눠서 관리를 한다.

예를 들어서 명령어(코드)들이 들어있는 세그먼트, 데이터들이 들어있는 세그먼트, stack 을 위한 세그먼트등 메모리 공간을 여러개의 구획으로 나누는 방식을 사용한다.

이렇게 하면 상호간의 잘못 접근하는 것을 막아주게 된다.

나눈 구회에 대한 정보들이 태이블에 저장되어있고 그것을 디스크립터 태이블이라고 부른다.

조금 더 자세히 보면 코드 세그먼트는 어디까지이고, 데이터 세그먼트는 어디까지인지 등의 범위를 가리키는지 저장된 태이블을 세그먼트 디스크립터 태이블, 그 태이블을 가리키고 있는 게 바로 세그먼트 레지스터 인 것이다.

CS : code segment

DS : data segment

SS : Stack segment

이렇게 각각의 세그먼트 레지스터는 그 태이블의 주소를 가리키고 있고, 그 태이블을 보면 코드 세그먼트의 시작 위치는 어디인지, 그 크기가 어느정도 인지 정보를 알 수가 있다.

이렇게 보듯 real모드와 protected모드에서는 세그먼트 레지스터의 동작 방식이 다르고 세그먼트의 의미마저 다르다는 것을 알 수가 있다.

2. Instruction Pointer (EIP) (명령 포인터) 

Instruction Pointer는 다음에 실행될 명령어의 주소를 가지고 있다.

앞에서 우리는 어떤식으로 명령어가 메모리에서 cpu로 보내지는지 실행이 되는지를 봤는데 그 과정에서 fetch를 하는 것이다.

이렇게 메모리에 있는 명령어가 cpu로 오게 되는 인출을 말하는데 이때 cpu내부의 Instruction Pointer 가 다음에 가져올 명령어가 몇번째 주소에 있는지를 저장된다.

이걸 보고 cpu는 instruction pointer에 있는 명령어를 fetch하게 된다. 당연하게도 fetch 후 EIP는 업데이트가 된다.

즉 요약하면 EIP는 다음에 읽어올 명령어의 주소를 저장하는데 사용되는 레지스터이다.

과거 책에서는 Instruction Pointer 가 아니라 program counter (pc)라고 많이 썻다.

루프라던가 브랜치를 구현하는 경우가 있는데 어떤 기계어들은 EIP를 임의의 값으로 바꿔주는 경우가 있다.

예를 들어 프로그램이 실행되다가, 다음 명령어의 위치를 쭉 내려가다가 임의의 위치로 다시 바꿔버리는 경우가 생기는데 그것의 가장 대표적인 예시가 루프이다.

루프는 instrution 포인터에 저장되어있는 주소값(번지수)을 임의의 번지수로 바꿔서(다시 앞으로 당겨서) 구현이 되는 방식인 것이다.

또는 다른 예시로 브랜치(if문)를 이렇게 구현을 한다.

if 문은 앞으로 가는게 아니라 true가 아닌경우 일정 부분을 스킵(점프)하고 떨어진 부분으로 갈 것이다.

3. EFLAGS Register

하나의 32비트로 된 값이 있을 때 각각의 비트들의 의미를 가지고 있는 것이다.

그게 어떤 경우는 control flag 일수도 있고 status flag 일수도 있다.

control flag 란

  • cpu의 명령을 컨트롤 하는 플래그 이다.
    • 예를 들어서 control flag에 해당되는 비트를 1로 바꾸면 cpu가 virtual 8086모드로 진입하는 경우가 예시로 들 수가 있겠다.
    • 또는 어떤 비트를 1로 설정했더니 보호모드로 갔거나.
    • 아니면 오버플로우가 발생 했을때 인터럽트를 거는 경우도 존재한다.
    • 명령이 끝나고 나면 cpu를 멈추게 할 수도 있다.
  • 이런식으로 cpu의 동작을 유도하는 플레그로 사용이 되는 flag가 control flag 이다.
  • 요약하자면 프로그램은 EFLAGS 레시즈서의 개별 비트를 설정해서 CPU의 작동을 제어할 수 있다.

status Flag

어떤 연산의 결과를 보여주기 위한 플래그로 사용이 되기도 한다.

  • The Carry flag (CF) 캐리가 발생 했는가 (자릿수를 벗어난)
  • The Overflow flag (OF) 오버플로우가 발생했는가? 
  • The Sign flag (SF) :앞의 연산 결과가 음수일 때
  • The Zero flag (ZF):결과가 0일때 
  • 나중에 어셈블리어를 공부할 때 더 자세히 설명할 것이다.
  • The Auxiliary Carry flag (AC) : 산술연산으로 8비트 피연산자에서 비트3에서 4로 캐리발생시 설정
  • The Parity flag (PF) : 데이터 손상이나 변경가능성 오류 검사에 사용되는 flag

앞에 있던 정보의 연산 결과를 보여주는 flag가 status플래그이다.

4. MMX Registers & XMM Registers

이 두 레지스터는 32비트 레지스터들이 발전하면서 점점 레지스터가 추가가 된 것이다.

MMX Registers

MMX technology 라는 기능이 추가가 되면서 그 기능을 쓰려면 MMX Registers에 값을 집어넣어야만 사용이 가능하다.

이 기능은 멀티미디어와 통신쪽에서 훨씬더 효율적으로 동작할 수 있도록 하는 기능들이 추가가 된 것이다.

이 기능을 위해 8개의 64비트 레지스터가 사용이 된 것이다.

실제로는 범용 레지스터는 32비트였지만 그 안에 64비트 레지스터도 있었다. 다만 모든 32비트 프로세서에 있는 레지스터는 아니다!!!

이런 레지스터는 SIMD (Single-Instruction, Multiple-Data) 라는 연산에 특화되어있다.

컴퓨터 그래픽스에서 많이 보게 되는 걸텐데, 연산은 하나인데 여러개의 데이터가 있는 경우의 연산을 말한다.

주로 이미지나 컴퓨터 그래픽스에 많이 사용된다.

이 기능을 쓰려면 mmx레지스터에 값을 집어넣어라..!

특징 (이런게 있다 정도로만 알아두자)

  • MMX 기술은 고급 멀티미디어 및 통신 애플리케이션을 구현할 때 인텔 프로세서의 성능을 향상시킵니다.
  • 8개의 64비트 MMX 레지스터는 SIMD(단일 명령어, 다중 데이터)라는 특수 명령어를 지원합니다.
  • MMX 명령은 MMX 레지스터에 포함된 데이터 값에 대해 병렬로 작동합니다.
  • 별도의 레지스터인 것처럼 보이지만, MMX 레지스터 이름은 실제로는 부동 소수점 유닛에서 사용하는 동일한 레지스터의 별칭입니다.

XMM Registers

이거는 MMX를 더 발전시킨 레지스터이다.주로 멀티미디어 어플리케이션에서 사용되는 것이다.

cpu의 버전 업에 의해서 생긴 것이다.

이건 8개의 128비트 레지스터이다.

특징 (이것도 이런게 있구나 정도…)

  • x86 아키텍처에는 XMM 레지스터라고 하는 8개의 128비트 레지스터도 포함되어 있습니다. 
  • SIMD 확장을 명령어 집합으로 스트리밍하는 데 사용됩니다.

5. Floating-Point Unit (FPU)

32비트 프로세서에는 Floating point uint 도 있다.

이것도 초창기 32bit 프로세서에는 없었다.

초창기 32bit 프로세서에서는 정수형 연산만 가능했다. 따라서 실수형 연산을 하려면 별도의 칩을 설치했어야만 했다.

그러나 intel486 부터 일반적인 cpu에서도 flaoting point 연산이 가능하게 됐다.

부동소수점 단위 레지스터

 

728x90