컴퓨터는 2진수를 사용해서 연산을 한다는 것은 익히 알려진 사실이다.컴퓨터 내부에서는 높고 낮은 전기 신호를 연속된 형태의 숫자로 변환하여 저장되고 사용된다.이것을 이진 비트(이진 자릿수,Binary bit) 라고 하며 비트(bit) 단위가 계산의 기본 단위가 된다.이 단위는 높음/낮음, on/off, 참/거짓, 1/0 의 두 값 가운데 한 값을 가지게 된다.이 이진 비트를 기준으로 컴퓨터에게 명령할 작업(명령어)을 숫자의 나열로 나타낸 것이 명령어 포맷이라고 할 수 있다.거의 모든 명령어는 레지스터를 사용하므로 레지스터 이름을 번호로 바꾸는 규칙이 있다.
MIPS 에서는 총 32개의 레지스터를 사용한다.
레지스터는 고속의 데이터 저장소로 MIPS 에서 산술연산을 하기 위해서는 데이터가 레지스터에
있어야 한다.
MIPS에서는 레지스터를 다음과 같이 피연산자(변수) 형식으로 제공한다.
설명 뒤의 괄호의 값은 레지스터 번호이다.
$zero : 상수 0을 가진 레지스터. (0)
$at : 큰 상수를 처리하기 위해 사용되도록 예약된 특수 레지스터 (1)
$v0,$v1 : 결과 및 수식 계산 값 (2~3)
$a0,$a1,$a2,$a3 : Argument, 함수에 사용되는 인자값을 담는 레지스터 (4~7)
$t0,$s1,.....,$t7 : Temporary, 임시저장 레지스터 (8~15)
$s0,$s1,....,$s7 : Save, 저장 레지스터 (16~23)
$t8,$t9 : Temporary, 임시저장 레지스터 (24~25)
$k0,$k1 : 운영체제 전용 레지스터 (26~27)
$gp : 전역(global) 포인터 (28)
$sp : 스택(stack) 포인터 (29)
$fp : 프레임(frame) 포인터 (30)
$ra : 복귀 주소(return adress) (31)
MIPS는 모든 명령을 word 단위(32bit, 4byte) 로 처리한다.명령어도 예외가 아니어서 모든 명령어는 32bit 단위로 처리되는데 기본적으로 다음과 같다.가장 기본적인 R-Type(Register Type) 명령어를 먼저 해부해보자.이 녀석은 보통 산술명령어들의 형식으로 사용된다.(add,sub 등..)
op code(6 bit)
|
rs(5 bit)
|
rt(5 bit)
|
rd(5 bit)
|
shamt(5 bit)
|
funct(6 bit)
|
각각의 칸을 필드(field) 라고 부르며 각 필드에는 다음과 같은 이름이 붙어 있다. * op code : 명령어가 실행할 연산의 종류, 연산자(operator) * rs : 첫 번째 피연산자 레지스터(source) * rt : 두 번째 피연산자 레지스터(target) * rd : 목적지 레지스터, 연산의 결과가 저장됨 (destination) * shamt : shift 연산시 이동할 자리이동의 양. * funct : 기능(function), 기능 코드위의 R-Type 같이 field 크기를 고정하는 경우 field 길이가 더 길어야 하는 경우에는 문제가 발생하기때문에 MIPS 설계자들은 하드웨어 설계원칙 '좋은 설계에는 적당한 절충이 필요하다' 에 따라서모든 명령어의 길이를 같게 하되, 명령어 종류에 따라 형식을 다르게 하는 방식을 만들어낸다.(세상에서 가장 어려운 것이 적당한 절충이 아닐런지..;;)그리하여 탄생한 것이 I-Type Instruction Format 이다.이 녀석은 데이터 전송 명령어의 형식으로 사용된다. (lw,sw 등..)
op code(6 bit)
|
rs(5 bit)
|
rt(5 bit)
|
Constant or address(16 bit)
|
이 녀석은 위의 R-Type 에서 뒤에 붙었던 필드 세 개를 하나의 필드로 묶어서 상수나 주소값이 들어가도록 고안되었다.16bit 주소의 경우 lw 명령은 베이스 레지스터 rs에 저장된 주소를 기준으로 하여 +-32,768byte 를저장할 수 있게 되었다.마지막으로 프로시져(procedure) 에서 사용되는 점프 명령어를 위한 명령어 형식이 있다.바로 J-Type 이다.(j 명령어)
op code(6 bit)
|
Target address(26 bit)
|
점프 명령어 같은 경우는 피연산자가 필요가 없이 원하는 address로 이동만 하면 되기에..위와 같이 조금은 단순무식한 그러나 매우 효율적이고 심플한 구조가 생겨나게 되었다.길게 적었는데 마지막으로 간단한 MIPS 명령어가 어떻게 formatting 이 되는지 적어보겠다.add $t1, $s2,$t0 # Temporary register $t0 gets $s2 + $t0
우선 add 연산의 경우 산술연산이므로 R-Type 이다.
MIPS Reference Data Chart 를 보며 각 field 의 값을 대입하면 다음과 같다.
0 (add opcode)
|
18 ($s2 Reg No.)
|
8 ($t0 Reg No.)
|
9 ($t1 Reg No.)
|
0 (not shift)
|
32 (add func)
|
다음을 2진수로 고치면 다음과 같이 변환된다.
☞ 000000 10010 01000 01001 00000 100000
lw $t0, 1200($t1) # temporary register $t0 gets A[300]
위와 마찬가지 방법이지만 lw 의 경우 데이터 전송 연산이므로 I-Type 이다.
35 lw opcode
|
9 ($t1 Reg No.)
|
8 ($t0 Reg No.)
|
1200(ten) (A[300] Adress)
|
A[300] 의 offset 이 1200 이 되는 이유는 300번째 배열요소의 값이기 때문 300*4 = 1200 이므로
1200을 넣어줘야 우리가 생각하는 A[300] 요소를 접근할 수 있다.
1200을 이진수로 변환하면 0000 0100 1011 0000 이며 이를 2진수로 고치면 다음과 같다.
☞ 100011 01001 01000 0000 0100 1011 0000
댓글
댓글 쓰기