[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

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로 시작하는 레지스터(사용하는 변수에 매핑되는 레지스터)가 존재

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로. 어떤 숫자의 작은 값을 가장 끝에 놓겠다는 것을 의미. 저장되있는 데이터를 그대로 저장하는 방식

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이면 충분 (25=322^5 = 32
  • 쓰기 주소: 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, 2i2^i만큼 곱한 효과)
  • shift right logical: 오른쪽으로 shift한 후 빈자리는 0으로 채움 (srl, 2i2^i만큼 나눈 효과) => 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 t0,0(t0, 0(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주차 강의 끝!!!
게시물에 사용된 사진은 강의에 나온 내용을 캡쳐한 것입니다.

좋은 웹페이지 즐겨찾기