School Lecture Study/Computer Architecture

[3-2] Arithmetic Operations in MIPS

vㅔ로 2021. 10. 1. 05:01
728x90

** 공부한 내용을 까먹을까봐 한글로 작성하는 글입니다.

** 강의 내용을 잘못 이해했을 수 있습니다. (지적 환영)

 

Add and subtract, three operands

 

- 두 개의 변수와 두 변수를 더한 값을 저장하는 destination이 존재한다.

- Regularity가 구현을 간단하게 만든다.

- Simplicity enables higher performance at lower cost (번역하는 것보다 이 문장이 나은 듯)

 

Ex) add a, b, c   // a = b + c

Ex) a = b + c + d; 

--> add a, b, c  // a = b + c

add a, a, d   // a + d

 

▶ C code = f = (g + h) - (i + h);

--> compiled MIPS code:

add t0, g, h    // g + h를 한 값을 temp 변수 t0 안에 담음.

add t1, i, j   // 위와 마찬가지

sub f, t0, t1    // f = t0 - t1    근데 뒤에서 sub 없다고 했었음. not real MIPS intructions.

 

Register Operands  (레지스터 연산?)

 

- 레지스터는 작은 공간을 갖고 있지만 엄청 빠르다. (Smaller is faster)

- registers are special locations built directly in processor

- MIPS는 32개의 register를 갖는다. ($0 ~ $31까지)

 

** Assembler names ** (어셈블리에서 쓰는 이름이려나 싶다)

temporary : $t0, $t1, ...  (중간에서 잠깐 쓰이는 레지스터들)

saved variables : $s0, $s1 ... (C code에서 변환될 때 있었던 변수들이라고 생각하면 편할 듯)

Ex) f = (g + h) - (i + h)

add $t0, $s1, $s2    // 이때 s1 s2는 각각 g, h이다.

add $t1, $s3, $s4    // i, h

sub $s0, $t0, $t1

 

※ 이 부분은 왜 나왔는지 모르겠긴 한데 일단 써본다.

char 1byte

short 2bytes

long 8bytes

float 4bytes

double 8bytes

int는 "주로" 4bytes임

32bit -> int 32bit

64bit -> int 64bit?? (64bit OS라고 해서 int 크기가 8bytes가 아닐 수도 있다.)

이유는 int의 크기는 인간이 사용하는 숫자를 대부분 cover하기 때문에 int 크기를 증가시키는 것은 공간 낭비임. 

 

→ int 보다는, int32_t, int64_t 이렇게 사용하는 것을 추천하신다고 함. (C에서 <stdint.h> 헤더 추가하면 사용 가능)

 

Memory Operands

 

Main Memory(RAM)에서는 여러 데이터가 저장됨. (배열, 구조체, dynamic data, malloc/free)

모든 변수들이 32개 밖에 없는 레지스터 안에 저장될 수는 없다.

arithmetic operations를 적용하려면 data transfer instructions가 필요하다. 

 

- Load values : 메모리에서 레지스터로

- Store result : 레지스터에서 메모리로

 

메모리에 접근하려면 memory address가 필요하다. (이때, 32bit computer에서는 32bit memory address를 사용하고, 64bit computer에서는 64bit memory address를 사용한다.)

단어들은 메모리 안에 일렬로 (연속적으로 들어간다는 뜻인듯) 정렬된다. Address는 4의 배수로 쓰인다(?)

 

** 교수님이 Structure로 예시 들어주심 **

struct mystruct {
	int a;  // 4 bytes
    char a;  // 1 byte
    short b;  // 2 bytes
}  // sizeof(mystruct) = 12 

struct mystruct {
	char a; // 1byte
    char b; // 1byte
    int c;
} // sizeof(mystruct) = 8

struct mystruct {
	char a;
    char b;
    int c;
    char d;
    char e;
} // sizeof(mystruct) = 12

struct mystruct {
	char a;
    char b;
    char c;
    char d;
    int e;
} // sizeof(mystruct) = 8

struct mystruct {
	int a;  // 4 bytes
    char a;  // 1 byte
    short b;  // 2 bytes
}__attribute((packed));  // 이렇게 쓰면 4bytes 배수로 안 나오고 합으로 나온다.
// sizeof(mystruct) = 7

32bit 메모리의 max size of memory는 2^32 bytes이다. 

2^32 bytes는 4GB로, 32bit 메모리의 메모리 주소는 4GB를 초과할 수 없다. 

 

32bit CPU에 32bit OS -> 가능

32bit CPU에 64bit OS -> 불가 (cannot install)

64bit CPU에 32bit OS -> 가능 (근데 4GB 이상의 메모리 주소 사용 불가. 고로 비추)

64bit CPU에 64bit OS -> 가능

 

 

Byte Ordering System

 

how to put multi-byte data in memory?

 

* LSB : Least significant bits

* MSB : Most significant bits

 

- Little Endian : LSB가 앞, MSB 뒤

- Big Endian : LSB가 뒤에, MSB가 앞에

Ex) 

0 0 0 10 (축약해서 쓴 것)이 있을 경우

0 0 0 10 으로 쓴 것은 Big Endian (사람이 생각하는 방식과 유사)

10 0 0 0 으로 쓴 것은 Little Endian

 

만약 Little Endian computer와 Big Endian computer가 통신을 하면 메모리 읽는 방식이 달라서 값이 다를 수 있다. 

그래서 기준을 정했는데 (network API/lib), netword byte order의 기준은 Big Endian이다. 

Little Endian의 경우에는 먼저 Big Endian으로 변환 후 전송하고, Big Endian 컴퓨터는 이를 받아서 다시 Big Endian으로 변환한다.

왜 Big Endian 에서도 변환하는 지 : 각 computer에 동일한 API를 적용하기 때문. (뭐라고 설명해야 할 지 잘 모르겠다.)

 

Memory Instructions Examples

 

load word (lw)와 store word (sw) 가 있다. 

이거는 예시로 이해하는 게 빠르다.

Ex) C code : g = h + A[8]   // 배열일 때 주로 사용하는 듯?

// s1이 g, s2가 h, A의 base address가 s3 (A 배열의 시작 포인터)

MIPS code : 

lw $t0, 32($s3)    // load word. 8 * 4를 해서 32임. &A[8] = 32 + $s3

add $s1, $s2, $s3  // g <- h + A[8]

 

Ex) C code : A[12] = h + A[8]

// h 가 s2, A 포인터가 s3

MIPS code : 

lw $t0, 32($s3)  // load word   &A[8] = 32 + $s3

add $t0, $s2, $t0  // h + A[8] <- h + A[8]  ( A[8]에 A[8] + h한 값이 들어있다는 뜻 )

sw $t0, 48($s3)  // store word  (store word를 하면 메모리로 들어간다.)

 

Register vs Memory

 

- 레지스터가 메모리보다 접근 속도가 빠르고, 사용하는게 간단하다.

- 메모리 데이터를 사용하려면 loads와 stores가 필요하다. (Arithmetic instructions는 레지스터에서만 작동함)

- 컴파일러는 최대한 많은 변수들을 레지스터에서 사용하고 싶어한다. 레지스터가 빠르기 때문.

그래서 많이 사용하는 변수는 레지스터, 적게 사용하는 변수는 메모리에 넣는다. 

-> 레지스터 최적화가 효율에 중요하다.

728x90

'School Lecture Study > Computer Architecture' 카테고리의 다른 글

Simple DataPath  (0) 2021.12.16
MIPS Instructions  (0) 2021.12.10
[5-2] Division  (0) 2021.10.21
[5-1] Overflow / Multiplication  (0) 2021.10.18
[3-3] Immediate Operands & Integer Wrapping & 보수  (0) 2021.10.01