이전 포스팅에서 어셈블리어의 한 종류인 RISC가 무엇인지를 보았다.
이번 포스팅에서는 RISC-V의 Instruction 들에 대해서 조금 더 알아보자.
💻 Arithmetic Operation(산술 연산)
산술 연산은 말 그대로 산술에 관한 명령들을 일컫는다.
RISC-V에서 산술 연산 명령어는 꼭 3개의 operand (== 피연산자)가 필요하다.
를
add a0, a1, a2
이 명령어를 보자.
add는 말그대로 덧셈 연산을 하는 명령어이다.
뒤 a0, a1, a2들은 레지스터들이고 각각의 위치에 따라 기능이 달라진다. 두번째, 세번째 레지스터의 값들을 더하여 처음 적인 레지스터에 저장해준다. 처음 나오는 레지스터는 rd(register destinaion)으로 쉽게 말해 목적지라고 볼 수 있다.
위 코드에서는 a1의 값과 a2의 값을 더하여서 a0에 저장하는 것이다.
c언어에서 a0 = a1+a2; 처럼 c언어와 같은 순서로 코딩된다고 생각하면 헷갈릴 일이 없을 것이다.
RISC-V의 산술 연산들은 반드시 3개의 피연산자들을 가진다.
그렇게 구성되어진 이유는 간단한 설계를 추구하기 때문이다.
add a0,a0,a1
위 코드도 똑같이 피연산자를 3개 가진다.
a0가 나왔다고 이건 잘못됬다고 생각하는 사람은 c언어를 조금이라도 배웠다면 없을것이라 생각한다.
a0 = a0+a1; 과 같다고 쉽게 추측이 가능하다.
이처럼, 간단함은 규칙성을 동반한다. 규칙성은 구현을 쉽게만들고 여러가지 성능적 장점을 가진다.
산술 연산에는 add, sub,mul,div 등이 있다.
레지스터는, CPU 안의 저장소로 산술 명령어들의 피연산자들은 이 레지스터에 저장되어야만 한다.
RISC-V에서 레지스터의 사이즈는 doubleword로 64bit다.
예전, word가 16비트 였던 시절이 있었는데, 그에 따라 word의 크기는 아키텍쳐들 마다 다르다.
MIPS에서는 doubleword가 32비트이기 때문에, 레지스터의 사이즈도 32bit다.
RISC-V의 레지스터의 개수는 32개이다.
이 레지스터들은 x + register numberd의 형태로 표현되어진다.
(x0,x1,x2 ..... x31)
C code로 짜여진 간단한 코드는 RISC-V에서 짜증나게 바뀐다.
내가 짜증나니깐 짜증나게 바뀐거 맞다.
x5,x6들은 temporary register로 레지스터들마다 쓰는용도가 다른데, 나도 자세히 아직 잘 몰라서 공부하고 바로 포스팅 하겠다.
💻 Memory Operands (메모리 연산)
세상은 넓고, 시간은 많지만 레지스터들은 제한되어있다. 그리고 데이타는 보통! 당연한 말이지만 제한된 레지스터보다 양이 훨씬 많을거다. 그래서 메모리와 레지스터간의 데이타 전송은 필수다.
먼저, 레지스터와 메모리를 비교해보자.
레지스터는 CPU안에 위치해있는 저장소고 메모리는 CPU 밖에 있는 저장소이다.
그렇기 때문에 둘은 성능에 있어서 차이가 난다.
먼저 접근 속도는 레지스터가 메모리보다 빠르다. 당연한 말이지만 가까우니깐 빠른거다.
허나, 메모리가 저장할 수 있는 공간의 크기가 레지스터보다 크다. 그래서 쓸모있는것들만 레지스터에 갖다 놓는다.
쓰기위해서 레지스터에 갖다 놨다가 나중에 되서 안쓸 것도 있을것이다.
그런것들은 메모리로 보내져버리는데 그걸 spilling 이라고 한다. spill은 영어로 물이 흘러 넘치다라는 뜻인데 잔의 크기는 정해져있고, 물을 계속 부으면 바닥으로 떨어지지 않겠는가?
저장하는것들이 많기때문에, 메모리가 레지스터보다 전력을 많이 사용한다.
이것들을 알고 있으면, 나중에 I-type을 사용하는 이유에 대해서 알게 될것이다.
I-type이 뭐냐면... 다음에 포스팅 하겠다.
어찌 되었든, 명령어는 많고! 레지스터는 적고! 그런데, 산술연산은 또 레지스터에서 해야되는 이 더러운 컴퓨터를 위하여 메모리 명령이 있는것이다. 그중 대표적인 것으로는 ld (load doubleword) 가 있다.
ld는 메모리에서 레지스터로 데이타를 복사해주는 명령어이다.
ld x2, 16(x3)
처음 입력받는 레지스터는 rd(resiter destination)이다. 두번쨰 16(x3)에서 x3은 메모리 주소이고, 16은 오프셋이다.
16(x3)이 의미하는 것은 x3 위치에서 16bit을 더한 값을 의미한다. 메모리를 배열로 생각한다면, x3위치에서 2byte(16bit) 를 더한 값은 배열에서 index 2번째 값을 의미한다.
💻 Endian
Endian은 하나의 word 안에 32-bit에 대한 순서를 정의한 것이다.
Big-endian과 Little-endian 둘로 나뉘는데,
가장 낮은 주소에
MSB(most significant byte)가 온다면, Big-endian,
LSB(least significant byte)가 온다면, Little-endian이다.
MSB는 최상위 자리수를 의미한다. 쉽게 말해 높은자리 수이다.
여기서 lowest address는 0이고, 12가 MSB이다.
RISC-V에서는 Little-endian을 사용한다.
💻 Immediate Operand(즉각 명령)
즉각명령이라고 부르는지는 모르겠고 내가 그냥 붙혀주었다.
x22에 4를 더해주고 싶다 치자.
우리가 알고 있는 산술계산으로는 4를 저장하고있는 메모리를 찾아야한다.
그것을 load 해주고 숫자가 담긴 레지스터를 x9라고하자,
add x22, x22, x9을 해야한다.
쓰기도 귀찮다. 편한방법이 없을까?
그래서 Immediate Operand가 있는 것이다.
addi x22, x22, 4
아까 add와 똑같이 피연산자를 3개 가진다.
C언어와 같이 x22 = x22+4와 같은 의미이다.
이름도 add immediate를 붙혀 addi이다. 이 즉각명령을 사용하는것이 더 빠르고 에너지를 덜 사용한다.
4는 명령어 비트 안에 포함되어 있는것이다.
💻 Constant Zero
레지스터 x0은 Zero라는 이름으로 RISC-V에서 사용되는데 이것은 특수 Register이다.
0을 가지도록 특수한 목적으로 만들어진 레지스터로 수정이 불가능하다.
몇가지 쓸모있는 기능이 있는데 두 개만 소개하고자 한다.
add x22, x21, x0
데이타를 옮기는 기능을 한다.
sub x22, x0, x22
x22 = -x22 즉, 값의 부호를 바꿔준다.
'2-2 > 컴퓨터 구조' 카테고리의 다른 글
[컴퓨터 구조] Data Hazard (0) | 2022.11.23 |
---|---|
[컴퓨터 구조] Pipeline (0) | 2022.11.23 |
[컴퓨터 구조] Type of Instructions (0) | 2022.10.11 |
[컴퓨터 구조] Instruciton (0) | 2022.10.02 |
[컴퓨터 구조] Performance (3) | 2022.09.19 |