Instruction : Language of Computer
ISA가 작동할 수 있도록 설계된 명령어이다.
ISA가 동일하면, 컴퓨터는 동일한 Instructions 를 지원한다.
하위버전에 대한 호환성은 유지하면서 확장 및 업그레이드를 진행한다.
서로 다른 컴퓨터는 서로 다른 Instructions Set을 가짐
But, commom한 부분이 있어서 배워두면 여러가지로 응용할 수 있다고 한다.
A Basic MIPS Instruction
a 는 Destination b, c 는 source
Machine Code : 000000010001100100100000000001000000 (Machine Friendly)
4개를 더해야하면 기계적으로 나눠보면 2개 2개 2개씩 총 3줄로 나눠서 계산을 진행한다.
C code f = (g + h) – (i + j);
translates into the following assembly code:
add t0, g, h || add f, g, h
add t1, i, j || sub f, f, i
sub f, t0, t1 || sub f, f, j
Register File이 존재하여 연산의 대상이 되는 것들을 ALU가 RF로부터 가지고 옴
Register가 많으면 많을수록 성능이 올라감
레지스터는 각각 32비트 (최근에는 64)를 가지고 있음
MIPS의 32Register는 다음과 같다
The 32 MIPS registers are partitioned as follows:
Register 0 : $zero always stores the constant 0
Regs 2-3 : $v0, $v1 return values of a procedure
Regs 4-7 : a3 input arguments to a procedure
Regs 8-15 : t7 temporaries
Regs 16-23: s7 variables
Regs 24-25: t9 more temporaries
Reg 28 : $gp global pointer
Reg 29 : $sp stack pointer
Reg 30 : $fp frame pointer
Reg 31 : $ra return address
한 단위를 워드라고 하고 워드 하나는 4비트
하지만 궁극적으로 데이터는 메모리에 있음
예를 들어
Add a, b, c <- abc는 사실 Memory에 있는것임
따라서 계산을 위해서는 메모리에 있는 데이터를 CPU로 옮겨야 함. 이 이동을 담당하는 명령어가 필요한데 이것이 바로 Store / Load.
Load word – lw $t0, Memory-address
addi 라고 쓰며 다른 포멧은 SW LW 명령어와 동일하다.
addi $s0, $zero, 1000
addi $s1, $s0, 0 # this is the address of variable a
addi $s2, $s0, 4 # this is the address of variable b
addi $s3, $s0, 8 # this is the address of variable c
addi $s4, $s0, 12 # this is the address of variable d
일반적인 메모리 Instruction의 구조는 다음과 같다
Memory Instruction Format
lw t3)
로드 / 목표 레지스터 / 소스주소
sw t3)
스토어 / 소스레지스터 / 소스주소
Array의 경우 주소를 지정해주는 특수한 숫자가 앞에 붙는다
Array의 경우 기본주소 ([0])을 레지스터에 넣음
그 후, Data Type에 따라 알맞은 할당공간만큼 늘려가면서 주소를 찾아냄 그 늘려가는 값이 바로 앞에 붙어있는 상수
ex) int = 4bytes
EX)
C code: d[3] = d[2] + a;
Assembly:
#addi instructions as before
lw s4)
lw s1)
add t0, $t0, $t1 sw $t0, 12(s4)
하나의 프로그램은
Stack, 메모리가 할당되면서 그 주소가 항상 기제되게 되어있음
Dynamic Data
Static Datea(Globals)
Text(Instruction)
MIPS ISA – 매우 평범한 포맷
3가지 Instrutcion format을 가짐
R, I, J
Instruction Category
6bit = 기능을 세분화 시키기 위해서 넣어둔 것 즉, OP instruction을 결정함
5bit = destination
5bit rt, rd는 입력값(혹은 계산할 두 값)
ALU OP / Source1/ Source2/ Destination/ Shift/ sub funct
op를 구분하고 funct로 작동 총 12비트
Shift는 Shift연산이 필요 할 경우 작동함
MIPS ISA State (Register & memory)
32 Register file($0 ~ $31) +LO HI(32bit lo hi 기록위해 만들어짐) PC (program Counter = 다음 계산을 기록하기 위한 Register)
Memory – 0 ~ 2^32 -1 까지 0x0000 0000 ~ 0xffff ffff
Immediate 숫자가 없으면 R 포맷
add $t0, $s1, $s2
sub $t0, $s1, $s2
Add or Sub Dest s1 s2
Arithmetic Instruction은 반드시 레지스터 안에 있어야한다. 하지만 32개의 레지스터만이 제공된다.
만약 프로그램이 많은 변수를 가지고 있다면 메모리를 참조하게 된다.
메모리는 대용량의, 1차원배열이다. 주소는 메모리의 인덱스로서 작동한다.
MIPS에는 load, store 두가지의 데이터 이동 명령어를 가지고 있다.
데이터는 레지스터 파일의 5bit 주소에 load 혹은 store 된다.
메모리 주소(32bits)는 base address registerdp offset 값을 더하는것으로 결정된다.
추가설명
Instruction 뒤에 오는 값들로 memory address를 만들어야 하지만, 32비트의 주소중에서 6비트의 op코드 연산에 쓰여서 바로 주소를 넣을 수 없음. 따라서 base address register 를 찾아서 offset value(앞에 붙은 숫자) 만큼 차이나는 memory에서load/ store하라는 명령을 만든다
MSB = Most significant Bits 1일경우 음수, 0일경우 양수
LSB = Least Significant Bites
MSB가 가장 작은 bit에 오면 big endian, LSB가 오면 little endian
이밖에도
같은 명령어가 있다.
8bit 문자를 32비트 words로 pack / unpack 하는 작업이 필요합니다.
ex)
sll $t2, $s0, 8 # st2 = $s0 << 8 bits
srl St2, Ss0, 8 # st2 - $s0 >> 8 bits
이러한 Shifts들은 logical 이라고 불리는데 이는 0으로 채워지기 때문이다.
and or nor 같은 bit-wise 논리 연산이 존재한다.
ex)
andi $t0, $t1, 0xFF00 # $t0 = $t1 & ff00
ori $t0, $t1, 0xFF00 # $t0 = $t1 | ff00
기본적으로는 순차적 수행
PC 가 다음수행 명령어를 저장함.
일반적으로는 수행 후 다음 PC를 가지고오도록 명령 (PC + 4 해서 다음 PC 지정)
Compiled MIPS code
bne $s3, $s4,Else (branch not equal)
뒤에오는 것이 같이 않으면 브랜치하라
뒤에오는 것은 LblA(라벨)
LblA : 같지 않으면 라벨로 가라 라는 명령어
I 포멧
6 5 5 16비트로 조건이 맞을 경우 브랜치가 일어나는 주소를 집어 넣음 (LblA – PC + 4) / 4
주소 = 상대주소
Example
if (i==j) f=g+h; (s3, s4)
else f=g-h;
bne s4,Else [s3 s4 가같지 않으면 else 수행 아니면 add 수행]
add $s0, $s1, $s2
j Exit
Else: sub s1,$s2
Exit:
16비트 주소가 어떻게 만들어 지는가?
기준점을 뭘로 잡을것인가?
PC는 워드단위로 값이 증가함
-> 워드단위로 값을 해주면 instruction 범위가 늘어남
16비트를 가지고 주소를 표현 할 경우 그 자체의 값이 메모리 주소값이면 워드로 표현하면 14비트만 워드 범위가 되기 때문에 14비트로 표현할 수 있는 범위는 -2^13 ~ 2 #13 -1 까지
즉 range 가 줄어들음
따라서 이 좁은 레인지를 늘려주기 위해 16비트를 워드 어드레스로 쓰겠다는 규칙을 정해서 사용하고 있음
살재 주소 : 명령을 두개 붙여서 정확한 워드 메모리 주소값을 만들어내야함
slt – set less than
~보다 자그면 ~ 해라
slt $s0, $s0, $s1
if $s0 < $s1 then
$t0 = 1
$t0 = 0
R 포맷 명령어
Less than
Slt $at, $s1 < $s2
#$at set to 1 iff
Bne $at, $zero, Label # $s1 < $s2
Less Than or equal to = Ble $s1. $s2, Label
Greater than= Bgt $s1, $s2, Label
Greater than or equal to = Bge $s1, $s2, Label
무조건 뛰어나가라
J type
J and jr type
Op(6 bit)(26 bit -> 절대주소값)
Pseudo direct adressing 을 지원함
컨디셔널 브랜치는 조건을 보고 Unconditional은 조건을 안본다
컨디셔널은 점프가 길지 않다 (앞에 비교를 넣기 떄문에 주소를 넣을 수 있는 범위가 작음)
따라서, 점프가 너무 멀리 가야 하는 경우 uncon jump를 이용해서 가게 만들어줘야함