[컴퓨터구조 요약 정리] 5. Instruction Set Architecture (ISA) 2

Embedded June·2021년 5월 21일
1
post-thumbnail

5.1. Memory 구조

image-20210511184000416
  • Reserved : 시스템에서 지정된 영역으로, 유저가 접근할 수 없다.
  • Text: 프로그램 코드가 저장되는 영역이다.
  • Static data: 프로그램의 전역변수나 const array 또는 string 이 저장되는 영역이다.
  • Dynamic data: Heap을 의미한다. 시스템이 메모리를 할당할 때 아래에서 위 방향으로 저장한다.
  • Stack: Function call 등 컴파일러가 위에서 아래로 데이터를 쌓으며 저장한다. 따라서 공간을 확보할 때는 stack pointer SP를 감산하면서 확보해야 한다.

5.2. Byte ordering

작은 주소가 큰 의미를 갖게 할 것인지, 큰 주소가 큰 의미를 갖게 할 것인지를 결정.

  • Big endian = 작은 byte일 수록 큰 주소를 의미함.
  • Little endian = 큰 byte일 수록 큰 주소를 의미함.

4-byte 상수 0x01234567을 저장할 때,

  • Big endian 이라면 0x100: 01, 0x101: 23, 0x102: 45, 0x103: 67 이렇게 저장된다.
  • Little endian 이라면, 0x100: 67, 0x101: 45, 0x102: 23, 0x103: 01 이렇게 저장된다.

5.3. Common Addressing Modes

이 부분은 아주 중요한 내용이므로 주의깊게 보자.

  1. Immediate addressing
    • 주어진 instruction에 operand에 address가 아니라 바로 상수 operand가 있는 경우다.
    • Operand 부분에 직접 상수가 저장돼있기 때문에 memory access가 불필요하다.
    • 가장 빠르다. (i.e. LOAD #3 = 상수 3을 load함)
  2. Direct addressing
    • 주어진 instruction의 operand에 가지고 올 operand의 주소가 있는 가장 일반적인 경우다.
    • 주어진 address에 operand가 저장돼있으므로 memory access가 필요하다.
  3. Indirect addressing
    • 주어진 instruction의 operand에 가지고 올 operand의 주소의 주소가 있는 경우다.
    • Instruction에 기재된 address를 타고 가면, 또 다른 주소가 있다. 그 주소를 타고 가야만 우리가 원하는 operand가 있다.
  4. Register direct addressing
    • Load-store architecture에서 사용하는 mode로, instruction에는 register의 index가 기재돼있다.
    • Register에 저장된 값을 operand로 가지고 온다.
  5. Register indirect addressing
    • Register에 operand가 저장돼있던 direct addressing과 달리, 이번에는 주소가 저장돼있다.
    • Memory 상의 그 주소에 접근해야만 원하는 operand를 구할 수 있다. (Memory access 필요)
  6. Displacement (Based or Indexed) addressing
    • Register indirect addressing 기반이기는 하지만, register의 저장된 주소가 operand를 저장하고 있는 주소가 아니라, base로 사용할 주소다.
    • Instruction에 기재된 상수값을 이 base 주소에 더한 새로운 주소가 operand가 저장된 주소다.
  7. Relative addressing
    • 현재 PC에 저장된 메모리에 임의의 상수를 더해서 operand의 주소를 가리키는 방법이다.

이것들 이외에도 정말 많은 addressing mode가 있다.

5.4. Instruction format

우리는 지난 시간에 instruction을 종류에 따라 ⓐ Data movement, ⓑ ALU, ⓒ Branch 3가지로 분류했다.

ISR에 따라 지원하는 instruction의 length가 다르다

  • 고정길이: 다음에 몇 bit를 읽어오면 명령어를 형성할 수 있을지 이미 알고있기 때문에 복잡도가 낮고 시간이 짧다. 하지만, 경우에 따라 instruction의 bit가 낭비되기도 한다.
  • 가변길이: 명령어에 따라 필요한 length만 사용하므로 stroage에 낭비가 없다. 하지만, 다음에 올 instruction의 length를 알 수 없기 때문에 word-aligned 해야만 한다. 고정길이 instruction 보다 비교적 decode가 복잡하다.

CISC

  • CISC에서는 최대한 많고 복잡한 addressing mode와 instruction을 지원하며 가변길이 instruction이다.
  • 도구가 많기 때문에 복잡한 연산을 최대한 적은 cycle에 수행할 수 있도록 최적화할 수 있다.
  • 하지만, 그런 최적화가 언제나 쉽게 가능한 것은 아니다.

RISC

  • RISC는 적고 단순한 addressing mode와 instruction을 지원하며 고정길이 instruction이다.
  • 일반적으로 하나의 instruction은 1 WORD 길이를 사용한다.
  • 1 Cycle에 1 instruction을 수행하는 것을 원칙으로 한다. (예외인 경우도 있다.)
  • CISC는 최적화로 간단히 할 수 있던 복잡한 작업에 몇몇 cycle을 더 사용해야 하기도 한다.
  • Memory access instruction을 LDASTA로 한정짓는다. (Load-Store architecture가 기본임.)
  • 컴파일러에 의존하는 ISA이므로 컴파일러의 성능에 영향을 크게 받는다.
  • RISC-V는 RISC의 5번째 버전으로 임베디드 마켓을 타겟으로 새롭게 재정의 된 ISA를 의미한다.

MIPS

  • RISC-V의 전신(predecessor) 격인 ISA다. RISC의 기본적인 제한이 모두 녹아들어있다.
    • Instruction length는 32-bit (1 WORD)로 제한되있다.
    • 32개의 gereral purpose register가 있다.
    • Memory access instruction을 LDASTA로 한정짓는다.
  • Branch 관련된 명령어를 조금 더 세부적으로 다양하게 지원한다.

5.5. RISC-V Operations

  • RISC-V의 설계 규범 ⓐ: 단순한 구조는 곧 일반화된 구조를 말한다.
  • RISC-V의 설계 규범 ⓑ: 작을 수록 더 빠르다.

Arithmetic operations

  • 모든 arithmetic operations는 OP dest op1 op2 형식을 따른다.

  • C언어로 f = (a + b) - (c + d) 라고 작성했을 때, RISC-V ISA로 컴파일 된 코드는 다음과 같다.

  • add t0, a, b	;;; temp t0 = a + b
    add t1, c, d	;;; temp t1 = c + d
    sub f, t0, t1	;;; f = t0 - t1

Register operations

  • RISC-V는 32개의 64-bit (2 WORD) register를 가지고 있다.

  • 0번 register는 항상 0으로 고정돼있다. (0이라는 상수를 만드는 데에 비효율적인 과정을 거쳐야 하기 때문이라고 함.)

  • RISC-V 역시 Load-store architecture이므로 register를 적극 활용해서 빠른 연산을 수행하는 데 집중한다.

  • RISC-V의 register들은 사용자가 custom하게 사용할 수도 있지만, n번째 register를 특정 용도로 사용하자는 규약이 있다. 예를 들면 아래 그림과 같다.

    image-20210511232006586

Memory Operands

  • RISC-V는 Little endian을 사용한다.
  • Memory access를 최대한 줄이기 위해 register를 많이 활용해야 효율적이고 빠른 연산이 가능하다.
  • C언어로 A[12] = h + A[8]; 이라는 코드가 있을 때, RISC-V로 컴파일하면 다음과 같다.
    ;;; h는 x21, A는 x22에 저장돼있다고 가정함.
    ld	x9,	64(x22)		;;; displacement indirect addressing
    add	x9,	x21, x9		;;; x9 = x21 + x9 = h + A[8]
    sd	x9, 96(x22)		;;; x9 -> A[12]
  • A = A[0] = x22 register에 저장되있으므로 8번 인덱스는 x22 register로부터 8 * 8 = 64-bit 떨어져있다는 것을 displacement addressing으로 나타냄.
  • A[8] 값을 x9 register에 load함.
  • h가 저장된 x21값과 A[8]이 저장된 x9를 더한 뒤 다시 x9에 덮어씌움.
  • x9값을 x22로부터 8 * 12 = 96-bit 떨어진 A[12]가 있는 address에 저장함.

Immediate operands

  • 상수값에 대한 연산을 수행할 때는 immediate addressing을 사용해서 instruction을 수행한다.
  • Immediate operand는 memory access가 불필요하므로 load operation이 필요없어서 빠르다.
  • addi x22, x22, 10 이런 식으로 표현한다.

profile
임베디드 시스템 공학자를 지망하는 컴퓨터공학+전자공학 복수전공 학부생입니다. 타인의 피드백을 수용하고 숙고하고 대응하며 자극과 반응 사이의 간격을 늘리며 스스로 반응을 컨트롤 할 수 있는 주도적인 사람이 되는 것이 저의 20대의 목표입니다.

0개의 댓글