Instruction Set 제공 - Instruction Set jegong

학부시절부터 운영체제란 과목에 항상 관심이 있었습니다..!(뭐 때문인지는 모르겠지만 '운영체제'라는 단어에서 오는 설렘?)

컴공이 아닌 저에게 운영체제란 과목은 옆학과가서 친구도 없이 교양으로 수강해야 가능한 그런 꿈의 과목이었습니다. 물론, 학점의 압박에 못이겨 타학과 전공을 듣는 것을 포기했습니다

개발자 면접을 준비하면서 운영체제라는 것을 알아야 한다는 즐거운(?) 소문을 들었고, 공룡책을 기반으로 하는 좋은 무료강의를 찾아 공부해보려고 합니다.

운영체제 공룡책 강의 👈 무료입니다

Instruction Set 제공 - Instruction Set jegong
시작!

1. 운영체제(OS)

운영체제 많이들 들어봤을 거라고 생각합니다. 초딩 때 준비했던 '워드프로세서 1급' 같은 필기시험에도 등장해서 무지성으로 외웠던.. 어디선가는 무조건 들어봤을 그런 단어입니다.

Instruction Set 제공 - Instruction Set jegong
Instruction Set 제공 - Instruction Set jegong

우리가 흔히 사용하는 window나 서버에서 많이 사용하는 linux를 운영체제라고 부릅니다.

"An operating system is a software that operates a computer system"

풀어보면, 운영체제는 컴퓨터 시스템을 작동시키는 소프트웨어라는 뜻을 가지고 있습니다.

1.1 컴퓨터 시스템은?

그럼 컴퓨터는 무엇인가요?

"A computer is a machine that processes the information"

컴퓨터는 정보를 처리하는 기계입니다.

1.2 그래서 어떻게 컴퓨터가 정보를 처리해?

컴퓨터는 bit 단위로 정보를 처리합니다. 즉, 10101과 같은 이진수로 이해를 하고 처리를 합니다.

1.3 컴퓨터는 누가 만들었지?

컴퓨터의 할아버지는 앨런 튜링은 튜링머신을 개발했습니다.
튜링머신 유튜브 🍎
컴퓨터의 아버지인 폰 노이만은 ISA라는 것을 개발했습니다.

ISA : Instruction Set Architecture

명령어 세트 구조라는 것을 개발했는데 이것이 지금 운영체제의 시초가 되었습니다.

Instruction Set 제공 - Instruction Set jegong

왼쪽이 앨런 튜링이 개발한 튜링머신입니다. Head, Tape, Turing Machines로 이루어져 있고 Universal Turing Machine에 의해 동작하도록 되어있습니다. 오른쪽에 보이는 현대의 운영체와 상당히 유사한 구조를 가지고 있다고 볼 수 있습니다. 그래서 컴퓨터의 할아버지(?)라고 부르는 것 같습니다.

폰 노이만

Instruction Set 제공 - Instruction Set jegong

A Stored-Program 즉, 메모리에 프로그램들을 저장하고 있는 컴퓨터를 만들었습니다.

1.4 그럼 프로그램은 또 뭐죠?

프로그램이라는 무의식적으로 쓰곤 하는데 정의에 대해서 한 번 생각해볼 필요가 있습니다.

"A program is a set of Instructions that tells a computer's hardware to perform a task"

프로그램은 명령어의 집합으로, 하드웨어에게 어떤 행동을 하라고하는 명령입니다.

Instruction Set 제공 - Instruction Set jegong

왼쪽은 C언어로 사람이 읽을 수 있는 코드입니다. 아주 작은 기능을 가지고 있는 프로그램입니다. 왜냐면? 여러가지 명령어로 이루어진 집합이기 때문입니다.
이 코드가 컴파일되면 오른쪽 그림처럼 기계어로 번역되어 컴퓨터 하드웨어에게 일을 시킵니다.

1.5 운영체제도 프로그램

다시 본론으로 돌아오면, 운영체제 또한 여러가지 명령어의 집합으로 하나의 프로그램입니다.

"Operating System is a program, running at all times on the computer to provide system services to application programs to manage processes, resources, user interfaces and so on"

"운영 체제는 프로세스, 리소스, 사용자 인터페이스 등을 관리하기 위해 응용 프로그램에 시스템 서비스를 제공하기 위해 컴퓨터에서 항상 실행되는 프로그램입니다"

쉽게쉽게

if(!운영체제) { /* 어떻게 되지 */ }

어떤 애플리케이션을 개발하기 위해서 개발자들은 여러가지 프로그래밍 언어를 사용해서 코딩을 합니다. 각자의 집에서 기능1, 기능2, 기능3 코딩을 하고 하나의 프로그램으로 합치려고 할 때 문제가 생깁니다..!

변수를 메모리에 저장하고, 프로그램을 실행하는 등 이런 태스크들은 공통적인 코드입니다. 각각의 개발자들이 이런 상황에 대한 코딩을 따로 한다면 비효율적일 수 밖에 없습니다. 더 나아가 하드웨어를 직접 컨트롤하는 것이기 때문에 매우 복잡할 수도 있습니다.

따라서 하나의 프로그램 즉, 운영체제라는 것을 만들어 하드웨어적인 부분과 애플리케이션을 컨트롤할 수 있게 했습니다.

즉, 운영체제는 하드웨어에 관한 지식이 없어도 쉽게 프로그램을 개발할 수 있도록 도와주는 하나의 커다란 소프트웨어라고 할 수 있을 거 같습니다.

Instruction Set 제공 - Instruction Set jegong

1. ISA란?
ISA(Instruction Set Architecture)라는 것은 하드웨어와 low-level 소프트웨어 사이의 추상화 인터페이스(Interface)이다. 쉽게 말해 OS와 HW 사이의 layer에 위치해 양자 간의 의사소통 방법을 제공해주는 약속이라고 보면 된다.
ISA는 CPU 프로세서가 읽고 이해하여 실행할 수 있는 기계어로된 명령어의 집합인데, 이를 좀 더 사람이 읽을 수 있도록 가독성을 높인 것이 어셈블리어(Assembly language)이다.

2. Instruction이란?
Instruction은 컴퓨터가 수행하는 일종의 일의 단위이다. 32 bit의 MIPS CPU를 기준으로 세 가지의 다른 format이 존재한다. R format, I format, J format이 그에 해당한다.
먼저 R format의 Field들은 opcode(연산의 종류), rs(첫 번째 Source operand의 Register number) rt(두 번째 Source operand의 Register number), rd(결과가 저장될 목적지의 Register number), shamt(Shift amount), funct(Function code)로 이루어져 있다.

각각의 Field는 다음과 같은 수의 bit를 사용한다.

R format
op: 6 bit
rs: 5 bit
rt: 5 bit
rd: 5 bit
shamt: 5 bit
funct: 6 bit
(총 32 bit)

그리고 I format의 경우는 뒤의 절반 16 bit를 Immediate라는 값으로 사용한다. 이 Immediate는 일종의 상수같은 개념인데, Operand를 모두 Register로부터 불러와서 사용하는 R format과는 달리, Instruction 내부에서 값 자체를 제공하는 것이다. 따라서 하나의 Operand를 레지스터로부터 받고, 16 bit의 Immediate 값과 연산을 수행하는 방식으로 동작한다.

각각의 Field는 다음과 같은 수의 bit를 사용한다.

I format
op: 6 bit
rs: 5 bit
rt: 5 bit
imm: 16 bit
(총 32 bit)

rd가 없어서 혼동이 될수도 있는데, 이항연산의 경우 rs와 imm의 값을 Operand로 사용하여 연산을 하고, 그 결과를 rd대신 rt에 저장하는 형태로 편법(?)을 사용한다. 그리고 또한 Immediate filed가 16 bit밖에 없는 점을 보아 4 Byte (32 bit) 의 Word를 사용하는 체계에서 상수의 값의 범위가 제한되어 버리지 않나하는 의문점도 생길 수 있다.
32 bit의 상수를 사용하려면 두 개의 Instruction을 사용하면 된다. lui(Load upper immediate)라는 Instruction과 ori(Or immediate)라는 Instruction을 연달아 사용하면 32 bit의 상수도 문제없이 읽어들일 수 있다.
우선 읽고자 하는 상수를 16 bit씩 절반으로 쪼갠 뒤에, 앞쪽(MSB쪽)의 16 bit에 해당하는 부분을 lui instruction을 통해 Immediate 값으로 제공하여 특정 Register에 넣어두고, 나머지 뒤쪽(LSB쪽)의 16 bit에 해당하는 부분을 Immediate 값으로 제공하여 앞서 사용한 Register의 값과 ori 연산을 수행하면 된다.
예를 들어, 0x1234_5678이라는 32 bit 의 상수를 $t0에 저장하려고 한다면,

lui $t0 0x1234
ori $t0 $t0 0x5678

이렇게 하면 된다. 그러면 처음 lui Instruction을 수행했을 때 $t0 <= 0x1234_0000, 그리고 ori 연산을 할 때 $t0 Register에서는

   0x1234_0000
| 0x0000_5678
---------------------
   0x1234_5678

이런식으로 연산이 진행된다. 두 번째 0x5678을 불러올 때 Sign extension이 아니라 Zero extension이 된다는 점에 유의하자.

그리고 마지막으로 J format은 Jump 관련 Instruction을 위해 사용되며, Field 구성은 매우 간단한 형태로 되어 있다.

J format
op: 6 bit
jump target: 26 bit

3. Appendix
어셈블리어를 통해 앞서 살펴본 것들 외에 MIPS의 여러 Instruction에 대한 예시들을 살펴보자.

add rd rs rt
rs와 rt의 값을 더해서 rd에 저장한다.
0 rs rt rd 0 32 (R format)

add rd rs rt
rs의 값에서 rt의 값을 빼서 rd에 저장한다.
0 rs rt rd 0 34 (R format)

addi rt rs imm
rs의 값과 imm 값을 더해서 rt에 저장한다.
8 rs rt imm (I format)

and/or/nor rd rs rt
rs의 값과 rt의 값으로 비트수준의 논리 연산(and/or/nor)을 수행한 뒤 rt에 저장한다.
0 rs rt rd 0 39 (R format)

andi/ori rt rs imm
rs의 값과 imm 값으로 비트수준의 논리 연산을 수행한 뒤 rt에 저장한다.
13 rs rt imm (I format)

sll/srl/sra rd rt shamt
rt의 값을 shamt 값만큼 shift 시킨 뒤에 rd에 저장한다.
sll은 Logical shift left, srl은 Logical shift right, 그리고 sra는 Arithmetic shift right를 뜻한다.
0 0 rt rd shamt 3 (R format)

sllv/srlv/srav rd rt rs
rt의 값을 rs에 저장된 값만큼 shift 시킨 뒤에 rd에 저장한다.
v가 붙은 것은 variable shift임을 뜻한다. 즉, Shift amount를 상수로 전달하기에는 값의 범위에 제한이 크기 때문에, Register에 저장되어 있는 32 bit의 값만큼 shift를 시키겠다는 뜻이다.
0 rs rt rd 0 7 (R format)

lw rt imm(rs)
rs에 저장된 값을 base address로 하여 imm값만큼의 offset을 더한 뒤, 이를 메모리 주소로 사용하여 메모리의 해당 위치에 저장되어 있는 값을 rt 레지스터에 불러온다. 즉, 메모리에서 레지스터로의 데이터 전송이다.
35 rs rt imm (I format)

sw rt imm(rs)
lw Instruction과 반대로, rt에 저장되어 있는 값을 메모리에 저장한다. 레지스터에서 메모리로의 데이터 전송이다.
43 rs rt imm (I format)

lb rt imm(rs)
Load byte Instruction이다. 메모리로부터 레지스터에 1 byte(8 bit)만큼의 데이터를 불러온다. 이때 signed 방식이기 때문에 불러온 8 bit 값은 레지스터의 LSB 끝쪽에 붙어서 저장되고 앞의 24 bit는 Sign extension이 이루어진다.
32 rs rt 1 (I format)

lbu rt imm(rs)
Load byte의 unsigned 버전이다. Zero extension이 된다는 것 외에는 lb와 똑같다.
36 rs rt 1 (I format)

sb rt imm(rs)
Save byte Instruction이다. sb와 반대로 레지스터(rt)에 있는 값 중 LSB 쪽의 8 bit를 base address + offset (rs + imm)에 위치한 메모리 주소에 저장한다. 해당 메모리 주소의 Word 중 1 byte만 건드린다. 나머지 3 byte는 전혀 건드리지 않기 때문에 값의 변화가 없다.
40 rs rt imm (I format)

lui rt imm
Load upper immediate Instruction이다. imm값을 레지스터의 MSB쪽 16 bit에 저장한다. 나머지 16 bit는 0으로 채워진다. 다른 I format Instruction과 다르게 인자가 두 개만 주어지는데, rs가 생략된 것이다. rs 부분엔 어떤 값이 들어오든 상관이 없다.
15 _ rt imm (I format)

beq/bne rs rt label
Branch on equal, Branch on not equal Instruction이다. rs와 rt가 다른 I format Instruction들과 달리 순서가 바뀌어 있는 것에 유의해야 한다. rs와 rt의 값이 같을 경우 label에 해당하는 곳으로 이동한다. label이란 C언어에서 goto 연산자와 함께 쓰이는 label과 대동소이하다. 예를 들어 bne $t0 $t1 skip 이라는 Instruction이 수행되면, $t0과 $t1의 값을 비교하여 다를 경우 skip이라고 지정된 부분으로 이동한다. 조건문이나 반복문 등에 폭넓게 사용된다.
4 rs rt label (I format)

slt/sltu rd rs rt
Set on less than Instruction이다. slt는 signed, sltu는 unsigned 버전이다. rs의 값이 rt의 값보다 작을 경우 rd의 값을 1로 셋팅한다. 만약 조건이 만족되지 않으면 0으로 셋팅한다.
0 rs rt rd 0 42 (I format)

slti/sltiu rt rs imm
slt Instruction의 I format 버전이다. Register에 저장되어 있는 값이 아닌 imm값과의 비교를 수행한다.
10 rs rt imm (I format)

4. References
http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html