Instruction Set
컴퓨터에서 사용되는 명령어들의 집합
- 서로 다른 컴퓨터는 서로 다른 Instruction Set을 가진다 (대부분 유사한 특징을 가지고 있긴 하다)
- 초기 컴퓨터는 아주 단순한 IS를 가졌지만, 시간이 갈수록 반도체는 발달했지만 메모리는 덜 발달하여 하나의 명령어가 많은 일을 할 수 있도록 점점 IS가 복잡해짐 (CISC)
- 많은 현대의 컴퓨터들은 간단한 명령어를 더 많이 씀 -> 하드웨어 구현을 심플하게 하고, 복잡한 명령어는 소프트웨어에게 맡기자 (RISC)
Arithmetic Operations
산술 연산 명령어 (Add and Subtract)
2개의 source, 1개의 destination
3개의 operand를 가진다 -> add a, b, c의 꼴 (a = b + c)
모든 산술 명령어는 이 form을 가진다.
Immediate Operands (상수 산술 연산)
- constant data는 Instruction에 상수를 사용한다. (addi $s3, $s3, 4)
- 뺄셈은 따로 지원하지 않고, 덧셈에 음수를 사용한다. (addi $s2, $s2, -3)
Register Operands
조금 복잡한 산술 연산을 보자.
f = (g + h) - (i + j);
이 때의 연산을 MIPS code로 컴파일하면
add t0, g, h # temp t0=g+h
add t1, i, j # temp t1=i+j
sub f, t0, t1 # f=t0-t1
이 때 t0, t1은 계산의 중간 결과를 잠시 저장하기 위한 용도로 쓰이는데, 이 때 잠시 저장하기 위해 쓰이는 것이 register이다.
MIPS는 32개의 32bits register file을 가진다.
- 0~31번까지의 번호를 매긴다.
- 32bits의 데이터는 1Word로 불린다. (MIPS에서는 4byte를 한 word로 단위를 잡는다.)
즉 위의 MIPS code를 제대로 표현하면
add t0, g, h # temp t0=g+h => add $t0, $s1, $s2
add t1, i, j # temp t1=i+j => add $t1, $s3, $s4
sub f, t0, t1 # f=t0-t1 => sub $s0, $t0, $t1
가 된다.
Byte Addresses
대부분의 아키텍처는 byte 단위로 메모리를 사용한다.
word를 가져올 때도, 4byte 단위로 읽어온다. (word가 4byte 단위이므로..)
Big Endian
- 가장 왼쪽 byte가 word address
Little Endia
- 가장 오른쪽 byte가 word address
- MIPS는 Big-endian을 쓴다.
Memory Operands
Array, Structure 등 복합적인 데이터들은 컴퓨터의 메인 메모리에 저장된다.
산술 연산을 하기 위해서는
- 메모리에서 레지스터로 값을 적재시키고 (load)
- 연산 결과를 레지스터에서 다시 메모리로 저장한다. (store)
메모리는 byte(8bits) 단위로 접근한다.
- 메모리는 용량이 매우 크기 때문에 저장 위치를 pointing 하기 위해서 address를 쓴다.
- address의 한 칸은 byte이다.
데이터는 word 단위로 메모리에 정렬된다.
- Instruction에서 다음 Instruction으로 옮긴다는 것은 word 단위로 움직였다는 것이다. (4byte 단위로)
예제
g = h + A[8]; 이라는 C code를 MIPS code로 컴파일 해보자. (g in $s1, h in $s2, base address of A in $s3)
MIPS code:
lw $t0, 32($s3) => A의 8번째 index의 값을 원하기 때문에 $s3에서 4 * 8 = 32bit만큼 움직여 A[8] 값을 꺼내온다.
add $s1, $s2, $t0 => 꺼내온 값과 h를 더한 값을 g에 넣는다.
Registers vs. Memory
레지스터는 메모리보다 data access 속도가 훨씬 빠르다.
그렇기에 레지스터를 이용하여 연산하는 것이 더 빠른 방법이다.
메모리의 데이터를 레지스터에서 이용하기 위해 load-store 방법을 이용한다.
- MIPS는 Load-Store Architecture이다.
컴파일러는 가능한 한 변수들을 레지스터를 이용하여 처리해야 한다. (그게 빠르니까!)
- 변수 처리를 위해 메모리에 접근하는 것을 최소화할 수 있도록 레지스터 최적화를 해야한다. (load-store 명령어를 적게 쓰도록)
Unsigned / Signed
Unsigned Binary Integers
- 부호가 없는 2진수 표현
- 0 ~ 2^n-1까지의 범위를 가진다.
- 32bits 체계일 경우, 0부터 2^32-1까지의 범위를 가진다.
2`s Complement Signed Integers
- 2의 보수체계를 사용한 부호가 있는 2진수 표현
- -2^(n-1) ~ 2^(n-1)-1까지의 범위를 가진다.
- 첫 번째 bit를 부호로 표현하고(sign bit), 0이라면 양수 1이라면 음수이다.
- 32bits 체계일 경우, -2^31 ~ 2^31 - 1까지의 범위를 가진다.
몇몇 수의 표현
- 0: 0000 0000 ... 0000
- -1: 1111 1111 ... 1111 (2의 보수 체계이기 때문에)
- Most-negative: 1000 0000 ... 0000
- Most-positive: 0111 1111 ... 1111
부호 변환
뒤집고, 1을 더한다. (0 -> 1, 1-> 0하고 1더한다)
x = 1001001 -> -x = 0110111
Sign Extension
수의 bit 범위 확장 (같은 수를 더 많은 bit를 사용하여 표현한다)
sign bit와 같은 값을 왼쪽으로 확장한다.
- 8bits -> 16bits로 확장한다고 할 때,
+2 : 0000 0010 => 0000 0000 0000 0010
-2 : 1111 1110 => 1111 1111 1111 1110
MIPS R-format Instructions
MIPS는 R, I, J-format의 간단한 Instruction Set을 가지고 있다. (RISC)
R-format Instructions은 주로 산술 연산을 위한 IS이다.
op (6bits): operation code (어떤 종류의 연산을 진행할지)
rs (5bits): 피연산자1이 들어있는 레지스터 번호
rt (5bits): 피연산자2가 들어있는 레지스터 번호
rd (5bits): 연산결과가 담길 레지스터 번호
shamt (5bits): shift 연산일 경우 몇 bit shift 할 것인지
funct (5bits): function code (opcode와 함께 어떤 종류의 연산을 할지)
- R-format Instructions는 2개의 source와 1개의 destination을 가진다는 특징이 있다.
I-format Instructions
상수와의 연산 또는 load/store에 쓰이는 Instruction Set.
op (6bits): opcode
rs (5bits): 피연산자1이 담겨있는 레지스터 번호
rt (5bits): destination 또는 피연산자2의 레지스터 번호
constant (16bits): -2^15 ~ 2^15-1의 수를 표현 가능
address (16bits): rs에 담긴 base address로부터 얼마나 떨어져있는지 (offset)
설계 원칙 4! 좋은 설계는 좋은 타협이 필요하다.
- Immediate arithmetic과 load/store inst.는 서로 다른 종류의 작업이지만, I-format으로 모두 표현할 수 있다.
- 가능한 format이 적도록 같은 크기로 표현 가능한 작업들을 묶어야 한다.
MIPS(RISC) Design Principles
1. Simplicity favors regularity
- 가능하면 단순하고 정규적인 format을 만들어라.
- 고정된 Inst.의 크기 등
2. Smaller is faster
- 작을수록 빠르다.
- 적은 수의 register, 적은 수의 Instruction Set을 만듦으로써 빠르고 작게 구현한다.
3. Make the common case fast
- 흔한 케이스를 빠르게 만들어라.
- 자주 사용되는 산술 연산을 register에서 하게 만들어 빠르게 만든다.
4. Good design demands good compromises
- 좋은 설계는 적당한 타협이 필요하다.
- MIPS의 Instruction Set은 3개의 format으로 모든 것을 표현한다.
MIPS Memory Access Instructions
MIPS에는 메모리에 접근하기 위한 2개의 data transfer instruction이 있다.
lw $t0, 4($s3) # memory부터 값을 가져와 t0에 저장
sw $t0, 8($s3) # memory에 t0 값을 저장
- I-format Instruction이다.
- lw $t0, 4($s3)에서 4는 byte단위이다. -> 즉 base address $s3에서 4byte 떨어진 곳에서 값을 가져온다는 뜻.