[Chapter 2] Instructions: Language of the Computer_1
KOCW에 공개된 영남대 최규상 교수님 컴퓨터구조 강의를 수강 후 정리한 내용입니다.
2.1 Instruction
1. Instruction Set
- 컴퓨터에서 사용되는 명령어들의 집합
- 서로 다른 컴퓨터는 서로 다른 instruction set을 가짐. 하지만 대부분의 경우 많은 부분을 공유
- 초창기 컴퓨터는 매우 단순한 instruction set(명령어의 개수가 많이 없음)을 가짐. 중간에 complex instruction set을 가지는 CPU가 있었지만, 최근 컴퓨터는 simple instruction set을 가짐
2. Instruction Set Architecture (ISA)
- Architecture라고도 함
- 하드웨어와 가장 low level의 소프트웨어(ex. 시스템 소프트웨어, 운영체제) 간의 인터페이스
- ISA를 사용해 필요한 정보를 instruction에 담아 CPU에 주면 하드웨어는 instruction을 실행
- instruction의 종류, 레지스터, 메모리, I/O 정보가 포함되어 있음
- ISA를 사용하면 똑같은 소프트웨어를 실행할 때 성능과 비용에 따라 다른 implementation이 가능. 같은 소프트웨어를 여러 개의 CPU에서 실행할 수 있음
- Application Binary Interface(ABI): ISA와 운영체제의 인터페이스를 합친 것
- user 관점에서 아주 중요. ABI가 같다는 것은 어떤 프로그램이 특정 컴퓨터에서 실행될 때 이 프로그램은 실행되고 있는 컴퓨터와 ABI가 같은 다른 컴퓨터에서 실행시킬 수 있음
2.2 Operations of the Computer Hardware
Arithmetic Operations
- user 관점에서 아주 중요. ABI가 같다는 것은 어떤 프로그램이 특정 컴퓨터에서 실행될 때 이 프로그램은 실행되고 있는 컴퓨터와 ABI가 같은 다른 컴퓨터에서 실행시킬 수 있음
Arithmetic Operations
Design Principle 1: Simplicity favours regularity
- 규칙성을 주면 구현할 때 훨씬 수월
- 간단하게 만들어야 낮은 가격으로 높은 성능이 가능
Example
- C code:
f = (g+h) - (i+j);
- Compiled 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
- 실제 모든 연산은 레지스터에서 이루어져야 함
2.3 Operands of the Computer Hardware
1. Register Operands
- 산술 연산은 레지스터를 사용
- MIPS는 32 X 32-bit 레지스터 파일을 가짐
- 레지스터에서 자주 사용하는 데이터들을 로딩해서 사용
- Numbered 0 to 31
- 32bit 데이터(4byte 데이터)를 'word'라고 부름
- Assembler names
- t로 시작하는 레지스터(temporary values를 저장해서 사용하는 레지스터)와 s로 시작하는 레지스터(사용하는 변수에 매핑되는 레지스터)가 존재
- 레지스터에서 자주 사용하는 데이터들을 로딩해서 사용
- Numbered 0 to 31
- 32bit 데이터(4byte 데이터)를 'word'라고 부름
- t로 시작하는 레지스터(temporary values를 저장해서 사용하는 레지스터)와 s로 시작하는 레지스터(사용하는 변수에 매핑되는 레지스터)가 존재
Design Principle 2: Smaller is faster
- 작을수록 더 빠르다
- 메모리의 크기 등이 작을수록 더 빠름
- 참조) 메인 메모리는 millions of locations으로 구성. 레지스터는 32X32-bit로 구성되어 있으므로 메인 메모리에 접근하는 시간보다 레지스터에 접근하는 시간이 더 빠름
Register Operand Example
- C code:
f = (g+h) - (i+j);
(f, ..., j in $s0, ..., $s4) - Compiled MIPS code:
add t0, g, h # $t0, $s1, $s2
add t1, i, j # $t1, $s3, $s4
sub f, t0, t1 # $s0, $t0, $t1
2. Byte Addresses
- 대부분의 컴퓨터에서는 메모리를 바이트 단위로 지정할 수 있음. 비트 단위로 access
- Alignment restriction: 32bit 프로세스의 경우 메모리 단위는 word 단위로 맞춰짐. 32비트씩 access 한다는 것은 기본 access 단위가 word라는 것
- Endian: data를 word 안에 어떤 방법으로 저장할 것인가
- Big Endian: leftmost byte를 word address로. 어떤 숫자의 큰 값을 가장 끝에 놓겠다는 것을 의미. 저장되어있는 데이터를 뒤집어서 저장하는 방식
- Little Endian: rightmost byte를 word address로. 어떤 숫자의 작은 값을 가장 끝에 놓겠다는 것을 의미. 저장되있는 데이터를 그대로 저장하는 방식
- Big Endian: leftmost byte를 word address로. 어떤 숫자의 큰 값을 가장 끝에 놓겠다는 것을 의미. 저장되어있는 데이터를 뒤집어서 저장하는 방식
3. Memory Operands
- Array, structures, dynamic data 등을 메모리에 저장
- To apply arithmetic operations
- 메모리에서 레지스터로 데이터 로딩
- 연산의 결과를 레지스터에서 메모리로 적재
- 메모리는 byte 단위로 access. 각각의 주소는 8-bit byte로 구성
- 메모리는 word 단위로 조정됨. 주소는 반드시 4의 제곱수로 구성
- MIPS는 Big Endian. MSB가 word의 least address에 저장됨
Memory Operand Example 1
- A: int형
- load word: 메모리로부터 데이터를 로딩
- 32($3): $3의 값(A의 시작 주소)에 32를 더한 메모리 주소
- lw $t0, 32($3): 메모리에서 32($3)에 있는 값을 가져와 $t0에 저장
Memory Operand Example 2
- A: int형
- add $t0, $s2, $t0: $t0에 있는 값에 $s2를 더해서 다시 $t0에 저장
- 마지막 줄: $t0에 있는 값을 48($s3)에 저장
4. Registers vs Memory
- 레지스터는 메모리보다 access하는 시간이 더 빠름
- Load-Store Architecture: 메모리의 데이터를 연산하고 싶은 경우 로딩을 해서 레지스터로 데이터를 가져온 후 연산을 하고 다시 메모리에 저장
- MIPS는 Load-Store Architecture. MIPS 프로세서는 명령어가 직접 메모리에 access해서 연산하지 못함
- 컴파일러는 register를 효율적으로 사용해야 함
- 메모리에 access하는 횟수가 줄어듦
- register optimization(레지스터를 최대한 활용하는 것)은 컴퓨터 아키텍처에서 중요한 주제!
Register 정리
- 메인 메모리에 access하는 것보다 훨씬 빠름
- 레지스터를 사용할 경우 컴파일러는 연산을 하는데 훨씬 더 수월해짐
- 코드의 집적도가 향상됨. 집적도가 높다는 것은 같은 일을 수행할 때 instruction이 적다는 의미. 즉, 코드의 길이가 짧아짐
- 메모리 같은 경우 access할 경우 32bit가 필요하지만 레지스터는 5bit가 필요하기 때문
5. MIPS Register File
- 32bit의 레지스터를 가짐. 두 개의 read 포트와 하나의 write 포트를 가짐
- 읽기 주소: src1 addr, src2 addr
- 저장 공간은 5bit이면 충분 ()
- 쓰기 주소: dst addr
- 쓸 데이터: write data
6. MIPS Register Convention
- $zero: 하드웨어. 읽기만 가능하고 쓰기는 불가능. 항상 값이 0
- MIPS에서 유용하게 사용
- 레지스터 값을 복사하고 싶은 경우: add $t2, $s1, $zero
- $at: 프로그래머는 사용하지 않고 어셈블러만 사용
- $a: function call할 때 사용
- $v: return 값을 저장할 때 사용
7. Immediate Operands
- 하나의 값이 상수 값을 가지는 경우
- ex) addi $s3, $s3, 4 => $s3 = $s3 + 4
- 뺄셈의 경우 지원하지 않음
Design Principle 3: Make the common case fast
- 자주 사용하는 case를 빠르게 만들어라
- Immediate Operands를 지원하므로 상수값을 바로 사용할 수 있음
- Immediate Operands는 instruction을 load하는 수를 줄여줌
2.4 Signed and Unsigned Numbers
1. 컴퓨터의 숫자 사용 방식
1. Unsigned Binary Integers
- 컴퓨터에서 숫자를 표현할 때 이진수를 사용
2. 2s-Complement Signed Integers
- 부호가 있는 integers를 표현할 땐 2의 보수를 사용
- 음수의 최솟값의 절대값이 양수의 최댓값보다 하나 큼
- 31번 bit(LSB)는 부호 bit: 0이면 양수 또는 0. 1이면 음수
- -(-2^(n-1)))는 표현할 수 없음
3. Signed Negation
- 부호를 바꿔줌. 보수(1이면 0으로 0이면 1로 바꿔줌)를 취한 후 1을 더함
4. Signed Extension
- 비트 수를 확장하고자 할 때 sign은 그대로 유지되어야 함
- addi: 상수값을 더할 때 extension이 발생
- lb(load byte, 바이트만 읽음), lh(load halfword, 2바이트만 읽음): 바이트를 load할 때 extension 발생
- beq, bne: displacement할 때 extension 발생 (뒤에서 다룸)
- sign bit와 unsigned bit 값을 왼쪽에 채우면 됨
2. 명령어에서의 숫자 사용 방식
- 모든 명령어는 binary로 표현
- MIPS 명령어는 32비트로 표현 (opcode: operation code의 수가 적음)
1. MIPS R-format Instructions
- op: operation code
- rs: source register, rt: target register, rd: destination register
- shamt: shift amount
- funct: function code (ex. 더하기, 빼기 ..)
- 예시
- shift 연산은 수행되지 않으므로 shamt 값은 0
- 두 번째 표는 binary 값으로 변경한 값
2. Hexdecimal (16진수)
- 사람이 이해하기 위해 16진수로 표현하는 경우가 많음
- 16진수는 4bit씩 표현. 16진수로 표현할 때 앞에 0x를 붙임
3. MIPS I-format Instructions
- I: Immediate를 의미
- Immediate arithmetic 또는 load/store 연산할 때 사용
- rt: destination 또는 source 레지스터 값
- constant 범위: (-2^15) ~ (2^15 -1)
- address: rs 레지스터 값이 더해지는 offset
Design Principle 4: Good design demands good compromises
- 서로 다른 두 가지를 하나로 만들어라
- Immediate arithmetic 과 load/store 연산은 별개의 operation이지만 I-format Instructions으로 두 개의 operation을 커버할 수 있음
- Instruction의 복잡성이 낮아지고 포맷이 단순해져 고성능을 얻을 수 있음
2.6 Logical Operations
1. 논리 연산
- Bitwise: 비트 단위로 연산을 수행
- 한 비트에서 특정 비트의 값을 추출하거나 추가하는데 유용하게 사용
1. Shift Operations
- shamt: shift 연산을 몇 번 할 것인가
- shift left logical: 왼쪽으로 shift한 후 빈자리는 0으로 채움 (sll, 만큼 곱한 효과)
- shift right logical: 오른쪽으로 shift한 후 빈자리는 0으로 채움 (srl, 만큼 나눈 효과) => unsigned에서만 가능
2. AND Operation
- 두 값이 모두 1이어야 1
- 특정 비트 값을 추출할 때 사용
3. OR Operation
- 두 값 중 하나라도 1이면 1
- 특정 비트의 값을 1로 세팅할 때 사용
4. NOT Operation
- 0을 1로, 1을 0으로 변환
- MIPS는 NOT operand를 가지고 있지 않음. nor operand(3개의 operand를 사용)를 사용해 not을 구현
- $zero의 레지스터 값은 모두 0이므로 $t1의 레지스터 값을 반대로 바꿔줌
2.7 Instructions for Making Decisions
1. Conditional Operations
- Branch: 어떤 조건이 true일 경우 labeled instruction으로 가고 false일 경우 다음 instruction 수행
Compiling If Statements
Compiling Loop Statements
- sll $t1, $s3, 2: $s3를 2비트만큼 왼쪽으로 이동
- $s3의 값에 4를 곱한 것과 같은 효과
- save는 integer array. 하나의 integer는 4byte.
- save[i]의 값을 찾기 위해서는 인덱스에 4를 곱한 후 더해주어야하기 때문에 위 연산을 수행
- add $t1, $t1, $s6: save의 주소의 시작값인 $s6과 $t1을 더해주면 save[i]의 주소값이 나옴
- lw t1): $t1에서 4바이트만큼 읽어서 $t0에 저장
- bne $t0, $s5, Exit: $t0, $s5가 같지 않으면 Exit. 같으면 addi 명령 수행
2. Basic Blocks
- 아래 두 조건을 만족시키는 연속된 명령어들의 집합
- 중간에 brach 관련 명령어가 없어야 함. 마지막 명령어에는 가능
- 중간에 branch target(labeled instructions)이 없어야 함. 시작 명령어는 가능
- 컴파일러는 basic blocks를 찾아 빨리 실행하는 역할
- 프로세서는 basic blocks 실행을 가속화시켜주는 역할
3. More Conditional Operations
- 어떤 조건이 true이면 1, false이면 0
- slt $t0, $s1, $s2: $s1의 값이 $s2보다 작으면 $t0 값은 1
- bne $t0, $zero, L: $t0의 값이 1일 경우 $zero와 값이 다르므로 L을 실행
3주차 강의 끝!!!
게시물에 사용된 사진은 강의에 나온 내용을 캡쳐한 것입니다.
Author And Source
이 문제에 관하여([Chapter 2] Instructions: Language of the Computer_1), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@slchoi/Chapter-2-Instructions-Language-of-the-Computer1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)