Register Operands | 레지스터 오퍼랜드
- 산술 Instruction(명령어)는 Register Operands를 사용합니다
- MIPS에는 32개의 32비트 레지스터를 사용한다.
- 자주 접근하는 데이터에 사용
- 0 ~ 31까지 번호로 이름을 사용
- 32bit 데이터느 "word"라고 불린다.
- 어셈블러의 이름
- 임시 변수(Temporary variables)에 대해서는 $t0, $t1, …, $t9
- 저장된 변수(Saved variables)에 대한 $s0, $s1, …, $s7
- 설계 원칙 2: 작을수록 빠르다
- c.f. 메인 메모리: 수백만 개의 위치를 가짐
Register Operands Example
- C code
f = (g + h) - (i + j);
//f, ... , j in $s0, ..., $s4
- Compiled MIPS code
add $t0, $s1, $s2
add $t1, $s3, $s4
sub $s0, $t0, $t1
Memory Operands | 메모리 오퍼랜드
- 메인 메모리는 복합 데이터들을 저장하기 위해 사용된다.
- 배열, 구조, 동적 데이터
- 산술 연산을 적용하는 방법
- 메모리에서 레지스터로 값 Load(불러오기)
- 레지스터에서 메모리로 결과를 Store(저장)
- Memory(메모리) 주소는 byte단위로 접근함
- 각 주소는 byte(8bit)로 이루어진다
- Words(단어들)이 메모리 상에서 정렬된다
- 주소는 무조건 4의 배수여야 한다
- MIPS는 'Big Endian'을 사용한다.
- Most-significant Byte(가장 큰 자릿 수(왼쪽)의 바이트)가 word(4byte)에서 가장 낮은 주소에 위치한다.
- Little Endian: Least Significant Byte(가장 작은 자릿 수(오른쪽)의 바이트)는 가장 낮은 주소에 위치한다.
< 이렇게 이해하기 !! >
리틀 엔디언(Little Endian)은 가장 낮은 주소에 가장 작은 자릿수의 바이트를 위치시키는 바이트 순서입니다.
빅 엔디언(Big Endian)은 가장 낮은 주소에 가장 큰 자릿수의 바이트를 위치시키는 바이트 순서입니다 .
Memory Example 1
- C code
g = h + A[8];
//g는 $s1에, h는 $s2에, A의 base address는 $s3에
- Compiled MIPS code
- index 8은 32(4*8)의 offset이 필요함
- 하나의 word는 4byte
lw $t0, 32($s3) # load word
add $s1, $s2, $t0
# 32($s3) => 32 <- offset, ($s3) <- base regiser
Memory Example 2
- C code
A[12] = h + A[8];
# h는 $s2에, A의 base address는 $s3에
- Compiled MIPS code
- index 8은 32의 offset이 필요함
lw $t0, 32($s3) # load word
add $t0, $s2, $t0
sw $t0, 48($s3) # store word
Register vs. Memory
- 레지스터가 메모리보다 접근하는 속도가 빠르다
- 메모리 데이터에서 사용하려면 load(로드) 및 store(저장)이 필요하다.
- CPU가 메모리에 직접 접근할 수 없기 때문에, 레지스터에만 직접 접근할 수 있습니다.
- 컴파일러는 가능한 많은 변수의 레지스터를 사용해야 한다.
- 자주 덜 사용되는 변수만 메모리로 연산한다.
- 레지스터 최적화는 중요하다
Immediate Operands | 즉각 피연산자
- 명령어에 constant data(상수)를 사용함
addi $s3, $s3, 4
- 뺄셈 명령어는 지원하지 않는다. 음수(-)인 상수를 사용하면 된다.
addi $s3, $s3, -2
- 설계 원칙 3: 흔한 경우를 빠르게 하라
- 작은 상수는 흔하다.
- 즉각 피연산자는 Load Instruction(불러오기 명령)이 필요 없다.
The Constant Zero | 상수는 0
- MIPS 레지스터의 0($zero)는 항상 상수0을 가지고 있다.
- 레지스터는 읽기만 할 수 있고 값을 쓸 수가 없다.
- 흔한 작업들에 유용하다.
- e.g 레지스터간의 이동(대입)이 가능하다
add $t2, $s1, $zero
# 쓰기는 불가능하지만 0을 더해 다른 레지스터로 이동이 가능하다.