상세 컨텐츠

본문 제목

[컴퓨터 구조] 2.3 Operands of the Computer Hardware

전공/컴퓨터 구조

by blacksmith16 2020. 10. 25. 17:12

본문

Instruction의 피연산자로 올 수 있는 것들에 대해 알아본다.

Register Operands

Arithmetic Instruction은 레지스터 피연산자를 사용한다. 앞으로의 설명은 MIPS 아키텍쳐 기준으로 한다.

  • 레지스터 : 프로세서에 존재하는 저장소
  • 레지스터는 32 bit의 공간을 가진다.
    • 32 bit 단위로 데이터를 자주 전달하기 때문에 1 word(= 32 bit) 라는 단위를 사용
  • 32개 레지스터가 존재한다.
    • 각 레지스터는 0 ~ 31의 번호가 붙어있다.
    • 더 많은 레지스터를 만들 수는 있지만 비용, 성능 면에서 32개로 유지
  • 어셈블러에선 레지스터에 용도에 맞는 이름을 붙이기도 한다.
    • $t0, $t1, ..., $t9 : 임시(temporary) 값을 저장할 레지스터
    • $s0, $s1, ..., $s7 : 보존할(saved) 값을 저장할 레지스터

앞 포스팅에서 들었던 예제 f = (g + h) - (i + j);를 레지스터들을 이용한 어셈블리로 변환해보자.
여기서 변수 f, g, h, i, j는 각각 레지스터 $s0, ..., $s4에 저장되어 있다고 한다.

add $t0, $s1, $s2    # $t0 = g + h
add $t1, $s3, $s4    # $t1 = i + j
sub $s0, $t0, $t1    # f = $t0 - $t1

Memory Operands

메인 메모리는 복합적인 데이터(배열, 구조체, 동적인 데이터)를 저장하는 데에 사용된다. 또, 레지스터는 32bit, 32개로 한정되어 있기 때문에 여기에 들어갈 수 없는 데이터가 메모리에 저장되기도 한다.

  • 메모리의 값에 산술 연산을 적용하기 위해서는 'Data Transfer Instruction'을 사용해야 한다.
    • Load : Memory -> Register, 메모리에서 값을 가져와 레지스터에 저장
    • Store : Register -> Memory, 레지스터의 값을 메모리에 저장
  • 메모리에 접근하기 위해서는 메모리 주소가 필요하다.
    • 메모리 주소는 byte 기준으로 되어 있음 (주소값은 특정 바이트를 가리킴. 비트 단위 X)
    • Word들은 메모리 상에 정렬되어 있음(메모리 주소는 4의 배수)
      • Load, Store는 기본적으로 word 단위로 이루어지기 때문에, 데이터를 4의 배수 위치에 두면 워드의 시작 주소는 무조건 00으로 끝나기 때문에 워드를 표현할 주소 공간을 2 비트 절약할 수 있음.
        (Ch 4에서 다루겠지만, 더 좋은 설명을 찾아서 차후에 보강하겠습니다..!)
    • MIPS에서는 'Big Endian' 방식을 사용
      • 워드 시작 주소에 Most-Significant Byte가 위치함
      • <-> 'Little Endian' : 워드 시작 주소에 Least-Significant Byte가 위치함
      • Example
        • [12 34 AB CD] : 1word 데이터(16진수)
        • [12 34 AB CD]가 메모리 주소 0xAAAAAAA0 에 저장될 때,
          • Big-Endian
            • (0xAAAAAAA0) - [12] : Most Significant Byte
            • (0xAAAAAAA1) - [34]
            • (0xAAAAAAA2) - [AB]
            • (0xAAAAAAA3) - [CD]
          • Little-Endian
            • (0xAAAAAAA0) - [CD] : Least Significant Byte
            • (0xAAAAAAA1) - [AB]
            • (0xAAAAAAA2) - [34]
            • (0xAAAAAAA3) - [12]

Memory Instructions Examples

Memory Instruction에는 lw (Load Word), sw (Store Word) 가 있다. 피연산자로는 목적지 레지스터, 오프셋, 베이스 레지스터가 있는데 말로 하는 것보다 사용 예시를 한 번 살펴보자

lw, sw

lw $t0, 32($s3)    # Load Word Example

우선, lw다. 여기서 $t0는 메모리에서 가져온 데이터를 담을 레지스터이다. 그리고 $s3는 접근할 메모리를 저장하고 있는 레지스터이고, base register라고 한다. 그리고 숫자 32는 Offset인데 (베이스 레지스터의 주소값 + Offset) 위치에서 최종적으로 데이터를 가져온다.
위 코드의 결과는 ($s3에 저장된 주소값 + 32) 위치에서 1 word를 가져와 $t0에 저장하는 것이다.

sw $t0, 32($s3) # Store Word Example

sw도 명령어 형태는 lw와 동일하다. 그리고 접근하는 주소를 계산하는 법도 (베이스 레지스터의 주소값 + Offset)으로 lw와 동일하다. lw와의 차이점은 $t0에 메모리의 값을 저장하는 것이 아니라, $t0에 있는 값을 해당 메모리 주소에 저장하는 것이다.

Example

이번에는 C 코드를 MIPS Instruction으로 변환하는 예제로 실용적인 사용법을 알아보도록 하자.

g = h + A[8];    // g: $s1, h: $s2, A의 베이스 주소: $s3(A는 int(4byte) 배열)

여기서 주목할 점은 A[8]의 값을 가져오는 방식이다. 포인터를 제대로 공부했다면 당연히 A라는 식별자가 배열의 첫 요소의 주소값을 가리키는 것과 A[8]은 베이스 주소값인 A에서 32(4 * 8)바이트 뒤에 위치한다는 사실 쯤은 알고 있어야 한다. 여기서는 부연 설명 없이 바로 변환하겠다. 이 예시에는 없지만 sw도 마찬가지 방식이므로 직접 한 번 시도해보자.

lw $t0, 32($s3)    # $t0 = A[8]
add $s1, $s2, $t0  # g = h + $t0

Immediate Operands

즉시값은 숫자, 메모리 주소 같은 상수를 직접 입력하는 방식의 피연산자를 말한다. 대표적인 Immediate Operation으로는 add의 Immediate 버전인 addi가 있다.

addi $s3, $s3, 4    # $s3 = $s3 + 4(Immediate)

subi는 없다. 대신, 즉시값으로 음수를 넣는 것으로 대체 가능하다.
MIPS에서는 상수 0을 대신할 수 있는 레지스터 $zero를 제공한다. $zero에는 값을 덮어쓸 수 없으며 $zeroadd를 이용하면 레지스터에 값을 복사할 수 있다.

add $t2, $s1, $zero    # $t2 = $s1

관련글 더보기

댓글 영역