토요일, 10월 15, 2016

ISA(Instruction Set Architecture와 MIPS Instructions


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

댓글 없음:

댓글 쓰기