| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- JPA
- 실무
- Hexagonal
- transactional
- Spring Data JPA
- Spring
- hexagonal architecture
- Layered Architecture
- Adapter
- Transaction
- JDBC
- springboot
- simplejpaRepository
- Today
- Total
Ezcho
[MIPS] MIPS연산자, 레지스터 정리 본문
Register
Reg 는 parameter 를 정의하는 역할을 한다.
레지스터는 총 32개가 있으며 0~31 까지의 번호를 매긴다.
또한 레지스터는 word단위이다, 1 word = 4byte 이다.
$a0~ $a3: arguments
$v0~ $v1: return Value
$t0 ~ $9: temPvalue 임시 지정된 값이다.
$s0 ~ $s7: savedValue 미리 저장된 값이다.
$gp: 정적 데이터 접근을 위해 사용되는 global pointer 이다. 메모리 내 static data 영역 접근을 위해 사용된다.
$sp: 스택 포인터 이다. 스택메모리 접근을 위해 사용된다.
$fp: frame pointer
$ra: 리턴 포인터 이다.
Memory Layout(구조)

C 코드가 프로그램이 되고, 프로그램이 실행되면서 프로세서가 된다.
메모리 구조는 0~ 증가하는 메모리 구조를 띄고있고 Stack메모리 만이 감소하는 형태를 보인다.
Reversed: 우리가 프로그래밍 하면서 주어진 binary 값들을 저장하는 영역이다.
Text: MIPS instructions가 저장되는, 즉 직접적인 코드가 기록되는 영역이다.
Static data: 전역변수를 저장, constant array, String등 우리는 여기 접근을 위해 $gp를 사용한다.
Dynamic data: heap, malloc, new(java)등 동적으로 할당되는 데이터를 저장한다.
Stack: 메모리의 가장 높은부분에서 내려오면서 할당한다. $sp로 접근한다.
Stack overflow문제가 발생할 수 있다.(Dynamic data, Stack)
Instruction Set
인스트럭션은 컴퓨터 연산의 가장 하위 부분이다.
HLL -> ABL -> HW representation 으로 연결된다.
HLL 은 우리가 잘 사용하는 C, C++, Java와 같은 언어이고 High-Leve Language 라고 부른다.
ABL 은 instruction을 텍스트화 한것입니다. Assembly Language 라고 부른다.
Hw representation은 bits(0과 1 로) instruction과 data를 인코딩 하는것을 말한다.
이중 ABL을 텍스트화 하고 그중에서도 명령어의 리스트가 Instructinon set이다.
add & sub
add &a, &b, &c //a = b+c
sub &c, &d, &e //c = d-e
좌측은 MIPS code ,우측은 C code 이다.
메모리연산 lw & sw
메모리는 1 word (4byte)단위로 구성되기 때문에 우리가 배열에 접근할 때도 메모리 주소를 이용해 주어야 한다.
Load Word 예시
//C code
g = h + A[8];
//g는 $s1에 , h는 $s2에, A의 first address는 $s3에 저장된다.
//MIPS code
lw $t0, 32($s3)
add $s1, $s2, $t0
A[8] 이라는 원소에 접근하기 위해서는......
1. 우선 A[0]의 메모리주소 $s3, A[8]을 저장할 temp값 $t0를 준비한다.
2. lw 명령어를 사용해(load word) $s3의 값에서 32bytes shift 한 값을 $t0에 저장한다.
3. 이후 $t0와 $s2를 더해 $s1에 저장한다.
-왜 32인가?.. 메모리의 한 영역은 1word(4byte)로 이루어져있다 그래서 index_8에 접근하기 위해 4x8=32 를 해준것이다.
Store Word 예시
//C code
A[12] = h + A[8]
//h는 $s2에, A의 first address는 $s3에 저장된다.
//MIPS code
lw $t0, 32($s3) //load word
add $t0, $s2, $t0
sw $t0. 48(s3) //store word
A[8]에 접근하기위해 위와 같은 방식으로 lw 해주었다.
이후 더한값을 새로운 Temp 에 저장 후
48/4 = 12 ,12index에 $t0를 store해주었다.
레지스터 와 메모리
1. 레지스터는 메모리보다 더 빠른 접근이 가능하다.
2. 메모리 연산은 로드와 스토어를 필요로 한다, 이 과정에서 더 많은 instructions 이 실행된다.
3. 컴파일러는 변수에 레지스터를 가능한 적게 사용해야한다. 즉, 레지스터 최적화가 중요합니다.(메모리 접근은 불가피하니까..)
논리연산자
C 에서 AND, OR, NOT 은 MIPS로 어떻게 표현할까?
$t1 = 00...00 0000 0011
$t2 = 00...00 0000 0101
이라고 가정해보자.
MIPS 에서의 and연산은 아래와 같이 표현한다.
and $t0, $t1, $t2
or $t0, $t1, $t2
항상 bits단위 연산을 하기 때문에
0011 & 0101 = 0001 이다.
따라서 $t0 == 0001 인 것이다.
Not 연산자
not 은 아래와 같이 표현한다.
nor $t0, $t1, $zero
Not 은 비트를 뒤집을 때 많이 사용한다 1's complement로 생각하면 편할 것 같다.
00..00 0000 1110
11..11 1111 0001
이렇게 뒤집힌다.
Shift 연산자
bits를 옮긴다고 생각하자. sll과 slr이 존재한다.
sll: Shift left logical의 경우 값이 왼쪽으로 이동하고 0비트로 채워진다.
slr: Shift right locical의 경우 값이 오른쪽으로 이동하고 0비트를 채워진다.
$t0 = 00/.../00 0111 일 때
sll $t1 $t0 2
위와 같은 코드를 수행하면
$t1 = 00/.../01 1100 이 된다.
왼쪽으로 2비트 옮긴것이다.
slr은 그 반대이니까 잘 생각해보자.
Conditional operations (조건연산자)
덧셈 뺄셈은 대충 알겠고, 그럼 If문이나 while 문은 어떻게 구성될까?
if문을 알기위해 우선 조건문을 구성하는 조건 연산자가 존재한다.
1. 동등연산자
//C code
if(a == b)
L1;
//MIPS code
beq rs, rt, L1
//C code
if(a != b)
L2;
//MIPS code
bne rs, rt, L1
틀린지 다른지 비교하는 연산자이다. 참일경우 L1으로 Jump한다.
beq(equal): 같을경우 L1으로 이동한다.
bne(not equal): 다를경우 L1으로 이동한다.
아래와 같이 동등연산자를 정의할 수 있다.
그럼 비교연산자는 어떻게 정의할까?
2. 비교연산자.
//C Code
if (rs < rt) rd = 1;
else rd = 0;
//MIPS
slt rd, rs, rt //rs와 rt를 비교해서 rd에 넣는데 참이면 1 거짓이면 0이다. rs<rt
//C Code
if (rs < constant) rt = 1;
else rt = 0;
//MIPS
slti rt, rs, constant //rs와 상수를 비교해서 rt에 넣는데 참이면 1 거짓이면 0이다.
//slt와 bne, beq를 함께 사용할 수 있다.
slt $t0, $s1, $s2 //if ($s1 < $s2), t0는 1또는 0이 할당된다.
bne $t0, $zero, L // branch to L
비교연산자는 slt라는 연산자를 사용한다.
slt(set on less than)적은것을 찾는것이다.
slt $t0, $s1, $s2 에서, s1<s2이면 참. 1을 $t0에 저장한다.
즉, slt $t0, $s1, $s2 => if($s1<$s2) $t0 = 1; else $t0 = 0; 이다.
이후 bne $t0, $zero, L 해서 t0가 참이면 0과 다르니까 L로 이동하여 if문 내부 진입이 가능하다.
lb, lbu, sb, lh, lhu, sh
기존의 lw, sw 는 offset에서 워드단위 연산을 한다.
근데 얘네는 word단위로 긁어오는게 아니라 byte 단위로 긁어온다.
lb: 1바이트를 가져와서 32bit(word)에 저장한다.
그럼 word의 구성은 상위24bits+가져온8bits(1byte), 상위 24bits가 MSB를 따라서 저장
즉 가져온 byte 가 1111 0001 일때 word는 MSB(최 상위 bit)값에 따라 111...111 1111 0001 이 된다.
lbu: 1바이트 긁어와서 word에 저장한다. 대신 unsigned leastBits를 0으로 한다. 1111 0001 일때,
상위24bits+가져온8bits 000...00 1111 0001 이다.
sb: 32bits 레지스터 값을 offset 에 1바이트 만큼 저장한다.
lh, lhu, sh 는 위와같다. 대신 half byte, 즉 4bits단위로 위 작업을 처리한다.
'Lecture > CSA' 카테고리의 다른 글
| [MIPS] MIPS instruction의 예제와 프로시저 콜링(함수 호출) (1) | 2022.11.04 |
|---|
