컴퓨터 언어에서 단어를 명령어(instruction)이라 하고, 그 어휘를 instruction set이라 한다.
앞으로의 글에서 사용할 명령어 집합은 RISC-V이다.
RISC-V는 UC Berkeley에서 개발되었다. RISC-V는 RISC-V International이라는 기구에서 관리하는 개방형 구조를 갖는다. 즉, 특정 회사의 소유물이 아니다.
1. 하드웨어 연산
기본적으로 모든 컴퓨터는 산술 연산이 가능해야 한다.
RISC-V 산술 명령어는 반드시 한 종류의 연산만 지시하고, 항상 변수 3개를 갖는다.
한 예시를 살펴보자.
add a, b, c
add 연산자는 두 변수 b와 c를 더해 그 합을 a에 넣으라고 컴퓨터에 지시한다.
2. 피연산자 (operand)
high-level language와는 다르게 RISC-V의 산술 명령어의 피연산자는 제약을 가지고 있다. 이 피연산자에는 하드웨어에 직접 구현된 특수한 위치에 있는 몇 곳에 있는 것만을 사용 가능하다. 이 위치를 Register라고 한다.
레지스터는 하드웨어 설계의 기본 요소인 동시에 프로그래머에게도 보이는 부분으로, 컴퓨터를 구성하는 벽돌과 같다.
RISC-V architecture에서 register의 크기는 32비트이다. 32비트를 한 덩어리로 처리할 때, 이 덩어리를 워드(word)라고 부르고, 64비트 덩어리는 더블워드(double word)로 부른다.
high-level language의 변수와 하드웨어 레지스터의 또 다른 점은, 그 개수가 한정되어 있다는 것이다. RISC-V에서는 32개의 레지스터가 존재한다. 즉, 산술 명령어의 모든 피연산자는 32개의 32비트 레지스터 중 하나여야 한다.
메모리 피연산자
프로세서는 소량의 데이터만 레지스터에 저장할 수 있지만, 컴퓨터 메모리는 수십억 개의 데이터를 저장할 수 있다. 따라서 배열, 구조체 등의 자료구조는 메모리에 보관하고, RISC-V의 산술 연산은 레지스터에서만 실행되므로 필요할 때 이 데이터를 레지스터로 불러온다.
메모리와 레지스터 간 데이터를 주고 받는 명령어를 data transfer instruction이라고 부른다. 메모리에 있는 word에 접근하기 위해 명령어는 메모리 주소를 지정한다. 메모리는 주소가 인덱스 역할을 하는 큰 1차원 배열이다.
load는 메모리에서 레지스터로 데이터를 복사해 오는 데이터 전송 명령이다.
lw x9, 8(x22)
RISC-V에서 load 명령어의 실제 이름은 lw(load word)이다. 위의 예시에서는 x22에 배열의 시작 주소가 저장되어 있다. 이 시작 주소에 인덱스 8을 더한 값이 접근하고자 하는 메모리 주소이다. 이 메모리에서 읽어온 데이터는 레지스터 x9에 임시로 저장된다.
여기서 상수부분(8)을 offset, 시작 주소가 저장되어 있는 레지스터(x22)를 base register라고 한다.
load와는 반대로 레지스터의 내용을 메모리로 복사하는 명령은 store라고 한다.
sw x9, 48(x22)
RISC-V에서 load 명령어의 실제 이름은 sw(store word)이다. 그 형태는 lw와 같다. 위 예시에서 x9에 있는 데이터를 48을 offset으로 하면서 x22를 base register로 사용한 메모리 주소에 저장한다.
offset의 사용에서 주의해야 할 점이 있다. 프로그램에서는 8비트로 구성된 byte를 많이 사용하므로 대부분의 컴퓨터는 byte 단위로 주소를 지정한다. word 주소는 word를 구성하는 4byte 주소 중 하나를 사용한다. 따라서 연속된 word의 주소는 4씩 차이가 난다.
x22에 배열 A의 시작 주소가 저장되어 있다고 가정해보자. 그러면 offset 0일 때는 A[0], offset 4일 때는 A[1], offset 8일 때는 A[2], ..., offset 48일 때는 A[12]에 접근하게 된다.
수치(immediate) 피연산자
프로그램의 연산에서 상수를 사용하는 경우가 많다. 이 상수를 수치 피연산자라고 한다.
수치 피연산자를 갖는 덧셈명령어는 addi(add immediate)라고 한다.
addi x22, x22, 4 // x22 = x22 + 4
수치 피연산자를 갖는 산술 명령어를 사용하면 매번 메모리에서 상수를 가져오는 것보다 연산이 훨씬 빨라진다.
상수 중 0은 또 다른 역할을 갖는다. 예를 들어 첫 번째 피연산자가 0인 sub 명령어는 레지스터 값의 부호를 바꾼다.
RISC-V에서 레지스터 x0의 값은 0으로 고정되어 있다.
'Computer > 컴퓨터구조' 카테고리의 다른 글
[컴퓨터구조] Arithmetic for Computers(1): 덧셈과 뺄셈 (0) | 2024.05.29 |
---|---|
[컴퓨터구조] Instructions, RISC-V(5): 프로시저(Procedure) (0) | 2024.05.29 |
[컴퓨터구조] Instructions, RISC-V(4): 논리 연산 명령어, 조건부 분기 (0) | 2024.05.29 |
[컴퓨터구조] Instructions, RISC-V(3): 명령어의 컴퓨터 내부 표현 (0) | 2024.05.29 |