명령어 lw,sw 그리고 메모리

한포도·2024년 3월 15일
0

Compter Architecture

목록 보기
4/8

👨🏻‍💻 명령어 : 컴퓨터 언어

ISA : Instruction Set Architecure

ISA란? 어셈블리어 및 기계어를 통한 명령어 집합 구조. 쉽게 말해서 로우레벨 명령어 의 집합이라고 생각하면 된다.여기서 명령어를 공부하면서 프로세서가 동작하는 방식에 대해 이해(폰노이만 구조)하는게 챕터2의 목표!

🙂폰 노이만 구조

  • 폰 노이만이 제시한 컴퓨터 구조이며, CPU와 메모리를 분리했다.
  • 메모리는 데이터와 명령어를 저장
  • 프로그램 내장방식
    - 하드웨어는 변경하지 않고 프로그램만 변경 가능하다.
  • 프로세서는 명령어를 처리하도록 설계
    - 제어 유닛, 산술 논리 장치 (ALU), 레지스터

🙃하버드 구조

  • 명령어용 버스와 데이터용 버스를 물리적으로 분할시킨 구조
  • 명령어와 데이터를 동시에 읽을 수 있으므로, 빠를 수 있음
  • 하드웨어의 복잡성이 증가

✅MIPS

MIPS 는 명령어의 대표적인 집합중 하나다.

명령어의 길이는 32비트

즉 4바이트 이며, 즉 워드 단위는 4바이트다. 4바이트의 길이로 변환된다.
32비트 중 n비트는 명령어를, 32-n 비트는 저장소와 같이 하나의 명령어는 32비트를 사용함.

MIPS 는 32 개의 32-bit 레지스터를 갖음

  • 자주 사용되는 데이터를 위해 사용됨(자주사용되는 것을 프로세서와 가깝게 두기 위해)
  • 0번 부터 31번
  • 32-bit 데이터는 워드라고 불림

레지스터의 어셈블러 이름

ex) $t~ $s~ 는 레지스터의 이름

  • $t0, $t1, …, $t9 for temporary values (임시 변수)
  • $s0, $s1, …, $s7 for saved variables (저장 변수)

메모리 피연산자

MIPS의 명령어에는 3가지 형식이 있다.
R,I,J 3개의 형식이 따르는데 각각 할당되는 비트가 정해져있다.

산술 명령어는 레지스터에 저장되있는 피연산자를 사용한다.

메인 메모리의 데이터들에 대해서 산술 연산을하기 위해서는 다음과 같은 단계를 따른다.

-- 메모리 to 레지스터로 데이터를 load
-- 결과를 레지스터 to 메모리로 store
-- 메모리 주소가 필요함

메모리의 주소

메모리에서 명령어나 데이터를 호출하기 위해 메모리의 주소가 필요하다.

ex)0x00000000, 0x00000001

또한 메모리는 1칸당 1바이트의 크기를 갖는다. 때문에 1Word를 저장하기 위해서는 4바이트, 즉 4칸의 메모리가 필요하다.

표현가능한 주소는 2^32 이기 때문에 2^32개 만큼의 주소가 만들어진다.

예시로 데이터는 밑과 같이 저장된다.

주소:   0x00000000  0x00000001  0x00000002  0x00000003
데이터:  0001 0010   0101 0110   1000 1001   1010 0001

때문에 뒤에 얘기할 메모리를 건너뛸때 사용하는 offset 은 4바이트씩 건너 뛰어야 한다. 다음 주소에 접근하기 위해서는 1바이트씩 네번 떨어져 있기 때문이다. 만약에 2바이트 뒤를 참조하게 된다면 데이터가 꼬일것이다.

32비트의 구조에서는 주소 길이가 32비트기 때문에 메모리의 한계는 2^32*1byte = 4GB이다.

그래서 32비트 구조의 컴퓨터에서는 4기가 이상의 램을 인식하지 못한다. 나때는

메모리의 저장 방식

메모리의 저장방식엔 두가지가 있다.

  • 빅엔디안과 리틀 엔디안
  • 동일한 주소에 저장 시에, 큰 수부터 저장할지/ 작은 수부터 저장할지 결정 (바이트 단위)
  • MIPS는 빅엔디안 방식 (Intel 계열은 리틀 엔디안)
    빅 엔디안의 경우 첫 주소에 16,다음 17 을 저장한다면 리틀 엔디안은 첫 주소에 0D부터 저장한다.

메모리 피연산자 예시 (load, 적재)

C code:
	g = h + A[8];
	g in $s1, h in $s2
	 base address of A (A[0]의 주소) in $s3
     
Compiled MIPS code:
	데이터도 메모리에서 1워드 (32비트) 씩 차지
	Index 8은 32 바이트만큼의 offset (오프셋)
		오프셋은 바이트 단위

	lw $t0, 32($s3) # load word
	add $s1, $s2, $t0

lw는 load word라고 해서 특정 주소의 값을 불러와 일시적 저장소에 저장한다. $s3는 A인덱스의 기본주소(시작주소)이며 $s3로 부터 32바이트 떨어진 주소를 로드 한다.
A[0]부터 A[7]까지 8개를 건너 뛰어야 하기 때문에 4바이트씩 8번을 건너뛰어야 한다.때문에 32바이트 떨어진 주소를 로드 하는 것이다.

워드단위로 4바이트는 1인데, 32바이트면 8로 써야되는거 아니냐?

그러게;;

명령어로 인덱스 주소를 작성할땐 바이트 단위로 작성한다.
만약 기본주소 즉 A[0]이라면 0($s0) 이렇게 작성하면 된다.

메모리 피연산자 예시 (store, 저장)

C code:
	A[12] = h + A[8];
 	h in $s2, base address of A in $s3
    
Compiled MIPS code:
	lw $t0, 32($s3) # load word
	add $t0, $s2, $t0
	sw $t0, 48($s3) # store word

기본적으로 A[8]을 불러온다. 아까와 같이 8개의 주소를 건너 뛰기 때문에 32바이트를 $s3에 추가해준다. $t0 레지스터는 temporal이기 때문에 그뒤에 $t0 과 $s2를 더한 값을 다시 $t0에 저장한다. 그후 $t0의 값을 $s3에서 48바이트 떨어진 주소에(메모리) 저장한다.

근데 메모리에 저장해야되는거 아님? 왜 레지스터에 저장함?

여기서 48($s3)는 $s3 레지스터에 저장된 값(= 배열 A의 기본 주소)에 상대적인 오프셋인 48바이트를 더한 주소를 나타낸다. 이는 메모리에서 데이터를 저장하거나 로드할 위치를 지정한다.

즉, $t0의 값을 레지스터 $s3에 저장하는게 아니라 $s3에 저장된건 메모리의 주소다. 48바이트만큼 떨어진 곳에 저장하셈~

profile
응애 개발맨

0개의 댓글