명령어(instruction)

명령어의(instruction)의 정의

  • 컴퓨터가 하드웨어에게 일을 시키기 위한 수단
  • 명령어는 하향식 접근구조
  • 다음 명령어를 가르키는 레지스터(instruction Pointer)에 따라서 명령어를 실행함

Instruction Pointer ?

  • 현재 실행되고 있는 프로그램의 실행코드가 저장된 메모리의 주소를 가르키는 상태 레지스터

    • ex) add명령어가 실행되고, 그 다음은 move명령어 실행된다면 add명령어가 실행되는 동안에는 instruction pointer에는 move명령어의 주소가 저장되어 있기때문에 move명령어로 이동한다.
  • 프로그램의 실행이 진행됨에 자동으로 증가함

  • 프로그램의 실행 순서가 변경되는 제어문이 실행될 때 자동으로 변경됨

    • ex) 하향식으로 접근하면서 조건에 맞지 않으면 instruction pointer가 다른 위치를 가르키게 해서 else구문의 명령을 실행하는 형태이다.

      if(A>B) {
      
      }
      else {
      
      }
  • 직접접근이 불가능한 레지스터

    • ex) 게임을 설치하다가 제품의 키를 입력하는 창이 뜬다. instruction pointer에 직접 접근해서 다음 포인터로 우회시킬 수 있다. (프로그램이 설계자의 의도되로 실행되지 않는 문제가 발생한다.)

명령어 집합구조(Instruction Set Architecture)

  • 프로세서가 인식해서 기능을 이해하고 실행할 수 있는 기계어
  • 명령어 집합구조는 1대1대응되는 어셈블리로 표현 가능함
  • 명령어 집합구조에는 MIPS,ARM,x86,RISC-V등이 있음

명령어 집합구조 설계

  • 명령어 집합 구조는 작성된 프로그램과 그 프로그램을 수행할 컴퓨터 하드웨어 사이의 인터페이스에 대한 완전한 정의 혹은 명세가 있어야 함
  • 하드웨어 기술이나 컴퓨터의 구성, 플랫폼이 될 운영체제등을 고려해야 하는 매우 어려운 작업
  • 연산의 종류 :
    • 처리연산, 제어연산, 입출력연산 등
  • 데이터 형식
    • 데이터의 의미, 데이터 값 저장방식(정수,실수,논리) 등
  • 명령어 형식
    • 명령어 구성부분을 나타내는 양식
  • 피 연산자를 위한 주소지정방식(Addressing Mode)
    • 피연산자의 위치를 명시하는 방법
    • 메모리 or 레지스터

명령어의 구조

  • 명령어는 크게 두 부분, 실행코드(opcode)와 피연산잔(operand)부분으로 구성됨

[01010101|00001111|00001110|00001101]
<--------><----------------------->
opcode 피연산자 필드
[ADD | R1 | R2 | R3]


하드웨어 연산

산술연산의 정의

  • 산술연산은 덧셈,뺄셈,곱셈,나눗셈의 사칙연산의 계산을 하는 것
  • 컴퓨터는 레지스터와 ALU를 통해 산술연산을 수행한다.

MIPS 산술명령어

  • MIPS 산술명령어는 반드시 한 종류의 연산만 지시

  • MIPS 산술명령어는 항상 변수 세개를 갖는 형식

  • 피연산자가 반드시 3개인 이유?

    • 간단하계 설계하기 위해서는 규칙적인 것이 좋음.
  • MIPS 산술 명령어를 통해 b,c,d,e의 합을 a에 넣는 경우
    1) add a,b,c # b와 c를 더하여 a 에 저장 // a = b + c
    2) add a,a,d # a와 d를 더하여 a에 저장 // a = a + d
    3) add a,a,e # a와 e를 더하여 a에 저장 // a = a + e

    mips 레지스터

    • 연산을 위하여 mips명령어 구조에서 제공하는 레지스터
    • 레지스터는 컴퓨터가 사용하는 변수라고 이해하면 편함

스택프레임

  • 함수가 실행될 때마다 자신만의 고유한 stack영역을 가질 수 있다.
  • 함수의 스택프레임 시작점은 fp가 가르킨다.
  • 함수의 종료시에 해제되고 리턴 주소로 복귀한다.
int add(int a, int b) {
    return a + b;
}
int main() {
    printf("%d",add(3,4);
    printf("Hello World");
    return 0;
}

add가 실행되면 스택프레임으로 이동하게 된다. 처음 스택프레임은 fp의값과 sp의 값이 동일한 형태이다. 이후, int a, int b를 선언하고 이 공간에 값을 저장하기 위해서, sp의 공간을 int형(4byte) 2배 크기만큼 늘리게 된다. 즉, 스택프레임은 총 8바이트를 움직이게 된다. add연산을 수행하고 수행된 결과값을 임시공간에 저장 했다가, 임시공간에 있는 데이터를 다시 v 레지스터에 저장한다. 그리고 첫번째 줄에 있는 printf함수를 호출하기 직전 상태로 return해야 하는데, 이 위치를 ra 레지스터에 저장한다. printf에 결과값 7이 출력되고, 그 이후에는 정상적으로 Hello World가 출력이 된다.

image.png

MIPS

고급언어와의 관계

  • A = B + C;
  • D = A - E;
  • A~E 는 $S1 ~ $S5에 저장되어 있다고 가정
  • add $s1,$s2,$s3
  • add $s4,$s1,$s5