Chapter 2. Instructions: Language of the Computer

박병준·2022년 4월 9일
0

컴퓨터 구조론

목록 보기
2/5

Instruction Set

명령어의 집합으로 소프트웨어와 하드웨어가 서로를 추상화 해서 바라보는 인터페이스입니다.
각 컴퓨터는 다른 instruction set이 있습니다.

RISC-V

학문적으로 만든 ISA라 공개 되어있다.

Arithmetic Operation

  • 더하기
    add a, b, c
    a = b + c
  • 빼기
    sub a, b, c
    a = b - c

C code
f = (g + h) - (i + j);
Compiled RISC-V code
add t0, g, h
add t1, i, j
sub f, t0, t1

Register Operands

32개의 32bit의 레지스터를 가지고 있습니다.

정해진 레지스터
x0: 상수 0
x1: return 주소
x2: stack pointer
x3: global pointer
x4: thread pointer
x5 ~ x7, x28 ~ x31: 임시
x8: frame pointer
x9, x18 ~ x27: saved registers
x10 ~ x11: function arguments/results
x12 ~ x17: function arguments

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

  • f: x19, g: x20, h: x21, i: x22, j: x23

Compiled RISC-V code(정확한 표현)
add x5, x20, x21
add x6, x22, x23
sub x19, x5, x6

Memory Operands

메인 메모리는 바이트 단위입니다.
RISC_V는 Little Edian입니다.

C code
A[12] = h + A[8];

  • h: x21, A의 주소: x22, A의 타입은 int

Compiled RISC-V code
lw x9, 32(x22)
add x9, x21, x9
sw x9, 48(x22)

Registers vs Memory

레지스터가 메모리보다 접근 속도가 더 빠르다.
컴파일러 입장에서는 레지스터를 적게 쓰도록 해야한다.

Immediate Operands

상수를 바로 계산하면서 로드하는 명령을 줄일 수 있다.

Compiled RISC-V code
addi x22, x22, 4


Representing Instructions

RISC-V에서는 32비트짜리 명령어를 사용한다.
명령어들을 각각의 포맷으로 묶어 놨다.

R-format Instructions

  • opcode: Instruction operation code
  • rd: 연산결과가 저장될 레지스터 번호 (Destination register number)
  • funct3: 3-bit 짜리 function code
  • rs1: 연산에 사용될 operand register number 1
  • rs2: 연산에 사용될 operand register number 2
  • funct7: 7-bit 짜리 function code, funct3과 합친 10-bit가 operation의 세부적인 기능을 결정한다.

I-foramt Instructions

  • R-format의 rs1부터 opcode까지는 동일한 형식이고, rs2가 불필요하므로 rs2 + funct7 영역을 합친 12-bit로 상수를 표현한다.
  • 각 포맷간의 형식을 비슷하게 만들어놨다.

S-format Instructions

  • Store명령은 destination이 필요없기 때문에 rd부분을 없애고 R-format과 비슷한 형식을 가지기 위해 상수부분을 나눴다.

Logical Operations

Shift Operations

  • shamt는 32비트 레지스터이기 때문에 5비트만 쓴다.

Conditional Operation

  • if-else 문 처럼 분기를 형성할 때 사용하는 operation이다.
  • beq (= Branch if equal, ==)과 bne (=Branch if not equal, !=)이 있다.
  • blt (= Branch less than), bgt (= Branch greater than)도 있다.
  • ble (= Branch less than or equal), bge (= Branch greater than or equal)도 있다.
  • Signed number는 위 명령어들을 사용하면 되고, unsigned number는 끝에 u를 붙힌 명령어를 사용하면 된다.

C code

if (i == j) f = g + h;
else f = g - h;
  • f: x19, g: x20, h: x21, i: x22, j: x23

Compiled RISC-V code

bne	x22, x23, Else
add	x19, x20, x21
beq 	x0, x0, Exit	//unconditional
Else: 	sub x19, x20, 21
Exit: 	...

Procedure Calling

  • jal x1, label 로 x1에 PC + 1값을 저장해서 돌아갈 주소를 확보하고 label로 branch한다.
  • jalr x0, 0(x1)으로 x1에 저장된 돌아갈 주소로 branch 한다.
  • x0은 돌아오기 직전 주소를 적어주는건데 함수 call이 끝나면 다시 돌아올 일이 없어서 저장이 안되는 x0을 적어준 것이다.

C code

int leaf_example (int g, int h,int i, int j) {
    int f = (g + h) - (i + j);
    return f;
}

Compiled RISC-V code

// g부터 x10에 저장된다. f는 x20에 저장된다. x5, 6은 임시공간.
leaf_example:		addi	sp, sp, -12		// Stack pointer를 3-Byte 확보.
					sd		x5, 8(sp)		// 임시공간 x5 공간확보
					sd		x6, 4(sp)		// 임시공간 x6 공간확보
					sd		x20, 0(sp)		// local variable f를 위한 공간확보
					add		x5, x10, x11	// g + h
					add		x6, x12, x13	// i + j
					sub		x20, x5, x6		/ f = x5 - x6
					addi	x10, x20, 0		// x10에 return value 저장
					ld		x20, 0(sp)		// 저장해뒀던 x20값 백업
					ld		x6, 4(sp)		// 저장해뒀던 x6값 백업
					ld		x5, 8(sp)		// 저장해뒀던 x5값 백업
					addi	sp, sp, 12		// Stack pointer 복구
					jalr	x0, 0(x1)		// 돌아갈 주소로 RETURN

Addressing


Synchronization

Load reserved

lr.w rd, (rs1)

  • 불러올 때 값을 따로 저장해 놓는다.

Store conditional

sc.w rd, rs2, (rs1)

  • 다른 프로세서가 불러온 값을 바꾸면 나는 저장을 실패한다.
  • 성공/실패 상태값을 rd에 저장한다.
again:		lr.w	x10, (x20)
			sc.w 	x11, x23, (x20)
            bne		x11, x0, again
            addi	x23, x10, 0

RISC vs CISC

Reduce Instruction Set Computer

  • 명령어가 간단하다.
  • 종류가 적다.
  • 메모리 레지스터가 많이 필요하여 트랜지스터가 많이 요구된다.

Complex Instruction Set Computer

  • 명령어가 복잡하다.
  • 종류가 많다.
  • 명령어 저장하는데 트렌지스터가 많이 요구된다.

CISC가 성능이 무조건 좋은 것은 아니다.
구현이 복잡해서 한 cycle이 오래걸리기 때문이다.

profile
뿌셔뿌셔

0개의 댓글