명령어 집합 아키텍처 (ISA)

명령어 집합 아키텍처 (ISA)

개요

명령어 집합 아키텍처(Instruction Set Architecture, ISA)는 소프트웨어와 하드웨어 사이의 인터페이스를 정의합니다. ISA는 프로세서가 이해할 수 있는 명령어의 집합, 레지스터, 메모리 주소 지정 방식 등을 명세합니다. 이 레슨에서는 ISA의 개념, CISC와 RISC의 비교, 명령어 형식, 그리고 다양한 주소 지정 방식을 학습합니다.

난이도: ⭐⭐⭐

선수 지식: CPU 구조 기초, 제어장치, 이진수 표현


목차

  1. ISA의 개념
  2. CISC vs RISC 비교
  3. 명령어 형식
  4. 주소 지정 방식
  5. 대표적인 ISA
  6. 연습 문제

1. ISA의 개념

1.1 ISA란?

┌─────────────────────────────────────────────────────────────────────────┐
│                    ISA: 소프트웨어와 하드웨어의 계약                      │
│                                                                         │
│    ┌─────────────────────────────────────────────────────────────────┐ │
│    │                     소프트웨어 (Software)                        │ │
│    │                                                                 │ │
│    │    ┌─────────────┐    ┌─────────────┐    ┌─────────────────┐   │ │
│    │    │ 응용 프로그램│    │   컴파일러   │    │  운영체제 (OS)  │   │ │
│    │    │  (C, Java)  │    │   (GCC)     │    │  (Linux, Win)  │   │ │
│    │    └─────────────┘    └─────────────┘    └─────────────────┘   │ │
│    └─────────────────────────────────────────────────────────────────┘ │
│                                   │                                     │
│                                   │ 추상화 계층                         │
│                                   ▼                                     │
│    ╔═════════════════════════════════════════════════════════════════╗ │
│    ║              ISA (Instruction Set Architecture)                 ║ │
│    ║                                                                 ║ │
│    ║    - 명령어 집합 (Instructions)                                 ║ │
│    ║    - 레지스터 (Registers)                                       ║ │
│    ║    - 데이터 타입 (Data Types)                                   ║ │
│    ║    - 주소 지정 방식 (Addressing Modes)                          ║ │
│    ║    - 메모리 모델 (Memory Model)                                 ║ │
│    ║    - 입출력 (I/O)                                              ║ │
│    ║    - 예외 처리 (Exception Handling)                             ║ │
│    ╚═════════════════════════════════════════════════════════════════╝ │
│                                   │                                     │
│                                   │ 구현 (Implementation)               │
│                                   ▼                                     │
│    ┌─────────────────────────────────────────────────────────────────┐ │
│    │                      하드웨어 (Hardware)                         │ │
│    │                                                                 │ │
│    │    ┌─────────────┐    ┌─────────────┐    ┌─────────────────┐   │ │
│    │    │   CPU       │    │   캐시      │    │     메모리       │   │ │
│    │    │  마이크로   │    │            │    │                  │   │ │
│    │    │  아키텍처   │    │            │    │                  │   │ │
│    │    └─────────────┘    └─────────────┘    └─────────────────┘   │ │
│    └─────────────────────────────────────────────────────────────────┘ │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

1.2 ISA가 정의하는 것들

구성 요소 설명 예시
명령어 집합 프로세서가 실행할 수 있는 연산들 ADD, SUB, LOAD, STORE, JUMP
레지스터 프로그래머가 사용 가능한 레지스터 x86: EAX, EBX / ARM: R0-R15
데이터 타입 지원하는 데이터 형식 바이트, 워드, 정수, 부동소수점
명령어 형식 명령어의 비트 인코딩 방식 R-type, I-type, J-type
주소 지정 방식 피연산자 위치 지정 방법 즉시, 직접, 간접, 레지스터
메모리 모델 메모리 접근 방식과 정렬 규칙 Little/Big Endian, 정렬 요구사항
예외/인터럽트 예외 상황 처리 방법 트랩, 인터럽트 벡터

1.3 ISA vs 마이크로아키텍처

┌─────────────────────────────────────────────────────────────────────────┐
│                    ISA와 마이크로아키텍처의 관계                         │
│                                                                         │
│    하나의 ISA ─────────────────────────────────────┐                    │
│         │                                          │                    │
│         │     여러 마이크로아키텍처로 구현 가능      │                    │
│         │                                          │                    │
│         ▼                                          ▼                    │
│    ┌──────────────┐    ┌──────────────┐    ┌──────────────┐            │
│    │ x86 ISA      │    │ x86 ISA      │    │ x86 ISA      │            │
│    │              │    │              │    │              │            │
│    │ Intel Core   │    │ Intel Atom   │    │ AMD Zen 3    │            │
│    │ (고성능)     │    │ (저전력)     │    │ (경쟁사)     │            │
│    └──────────────┘    └──────────────┘    └──────────────┘            │
│                                                                         │
│    동일한 프로그램이 모든 구현에서 실행 가능!                            │
│                                                                         │
│    ┌─────────────────────────────────────────────────────────────────┐ │
│    │                         비유                                    │ │
│    │                                                                 │ │
│    │    ISA = 자동차 운전 인터페이스 (핸들, 페달, 기어)               │ │
│    │    마이크로아키텍처 = 엔진 구현 (가솔린, 디젤, 전기)             │ │
│    │                                                                 │ │
│    │    → 운전자는 엔진 종류와 관계없이 동일한 방식으로 운전           │ │
│    └─────────────────────────────────────────────────────────────────┘ │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

2. CISC vs RISC 비교

2.1 CISC (Complex Instruction Set Computer)

┌─────────────────────────────────────────────────────────────────────────┐
                              CISC 특징                                   
                                                                         
    철학: "하나의 명령어로 복잡한 작업 수행"                              
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
                         CISC 명령어 예시 (x86)                        
                                                                      
        REP MOVSB     ; 메모리 블록 복사 (반복 + 이동)                 
                                                                      
          명령어가 수행하는 작업:                                  
        1. ECX 레지스터  확인 (반복 횟수)                            
        2. ESI에서 바이트 읽기                                        
        3. EDI로 바이트 쓰기                                          
        4. ESI, EDI 증가/감소                                         
        5. ECX 감소                                                   
        6. ECX > 0이면 반복                                           
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    특징:                                                                
    ┌───────────────────┬────────────────────────────────────────────┐  
     명령어           많음 (수백 ~ 수천 )                         
    ├───────────────────┼────────────────────────────────────────────┤  
     명령어 길이        가변 길이 (1 ~ 15 바이트)                     
    ├───────────────────┼────────────────────────────────────────────┤  
     주소 지정 방식     다양함 (12+ 모드)                             
    ├───────────────────┼────────────────────────────────────────────┤  
     메모리 접근        명령어에서 직접 메모리 참조 가능              
    ├───────────────────┼────────────────────────────────────────────┤  
     실행 사이클        명령어마다 다름 (1 ~ 수십 사이클)             
    ├───────────────────┼────────────────────────────────────────────┤  
     제어장치           마이크로프로그램 방식 (주로)                  
    └───────────────────┴────────────────────────────────────────────┘  
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

2.2 RISC (Reduced Instruction Set Computer)

┌─────────────────────────────────────────────────────────────────────────┐
                              RISC 특징                                   
                                                                         
    철학: "간단한 명령어를 빠르게 실행"                                   
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
                         RISC 명령어 예시 (MIPS)                       
                                                                      
        메모리 복사를 위한 명령어 시퀀스:                              
                                                                      
        loop:                                                         
            lb   $t0, 0($s0)      ; 소스에서 바이트 로드               
            sb   $t0, 0($s1)      ; 목적지에 바이트 저장               
            addi $s0, $s0, 1      ; 소스 포인터 증가                   
            addi $s1, $s1, 1      ; 목적지 포인터 증가                 
            addi $t1, $t1, -1     ; 카운터 감소                        
            bne  $t1, $zero, loop ; 0이 아니면 반복                    
                                                                      
        6개의 간단한 명령어로 분해                                     
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    특징:                                                                
    ┌───────────────────┬────────────────────────────────────────────┐  
     명령어           적음 (수십 ~ 백여 )                         
    ├───────────────────┼────────────────────────────────────────────┤  
     명령어 길이        고정 길이 (32비트)                            
    ├───────────────────┼────────────────────────────────────────────┤  
     주소 지정 방식     제한적 (3-5 모드)                             
    ├───────────────────┼────────────────────────────────────────────┤  
     메모리 접근        Load/Store만 (산술은 레지스터만)              
    ├───────────────────┼────────────────────────────────────────────┤  
     실행 사이클        대부분 1 사이클 (파이프라이닝)                
    ├───────────────────┼────────────────────────────────────────────┤  
     제어장치           하드와이어드 방식                             
    └───────────────────┴────────────────────────────────────────────┘  
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

2.3 CISC vs RISC 상세 비교

┌─────────────────────────────────────────────────────────────────────────┐
│                        CISC vs RISC 비교표                               │
├──────────────────────┬─────────────────────┬────────────────────────────┤
│        항목          │       CISC          │          RISC              │
├──────────────────────┼─────────────────────┼────────────────────────────┤
│ 대표 ISA             │ x86, x86-64         │ ARM, MIPS, RISC-V          │
├──────────────────────┼─────────────────────┼────────────────────────────┤
│ 명령어 형식          │ 가변 길이           │ 고정 길이                  │
│                      │ (1-15 바이트)       │ (4 바이트)                 │
├──────────────────────┼─────────────────────┼────────────────────────────┤
│ 레지스터 수          │ 적음 (8-16개)       │ 많음 (32개 이상)           │
├──────────────────────┼─────────────────────┼────────────────────────────┤
│ 메모리 연산          │ 모든 명령어 가능    │ Load/Store만               │
├──────────────────────┼─────────────────────┼────────────────────────────┤
│ 컴파일러 복잡도      │ 낮음                │ 높음                       │
├──────────────────────┼─────────────────────┼────────────────────────────┤
│ 하드웨어 복잡도      │ 높음                │ 낮음                       │
├──────────────────────┼─────────────────────┼────────────────────────────┤
│ 파이프라이닝         │ 어려움              │ 용이                       │
├──────────────────────┼─────────────────────┼────────────────────────────┤
│ 코드 밀도            │ 높음                │ 낮음                       │
├──────────────────────┼─────────────────────┼────────────────────────────┤
│ 전력 효율            │ 낮음                │ 높음                       │
├──────────────────────┼─────────────────────┼────────────────────────────┤
│ 주요 사용처          │ 데스크톱, 서버      │ 모바일, 임베디드           │
└──────────────────────┴─────────────────────┴────────────────────────────┘

2.4 현대적 관점

┌─────────────────────────────────────────────────────────────────────────┐
│                       현대 프로세서의 융합                               │
│                                                                         │
│    현대 x86 프로세서 (Intel/AMD):                                       │
│    ┌─────────────────────────────────────────────────────────────────┐ │
│    │                                                                 │ │
│    │         x86 CISC 명령어                                         │ │
│    │              │                                                  │ │
│    │              ▼                                                  │ │
│    │    ┌─────────────────────┐                                      │ │
│    │    │  명령어 디코더       │                                      │ │
│    │    │  (CISC → micro-ops) │                                      │ │
│    │    └──────────┬──────────┘                                      │ │
│    │               │                                                 │ │
│    │               ▼                                                 │ │
│    │    ┌─────────────────────┐                                      │ │
│    │    │  RISC 스타일 코어   │                                      │ │
│    │    │  (micro-ops 실행)   │                                      │ │
│    │    │  - 파이프라이닝     │                                      │ │
│    │    │  - 슈퍼스칼라       │                                      │ │
│    │    │  - 비순차 실행      │                                      │ │
│    │    └─────────────────────┘                                      │ │
│    │                                                                 │ │
│    │    결론: 외부는 CISC, 내부는 RISC!                               │ │
│    └─────────────────────────────────────────────────────────────────┘ │
│                                                                         │
│    ARM 프로세서:                                                        │
│    ┌─────────────────────────────────────────────────────────────────┐ │
│    │    - 기본 RISC 설계 유지                                        │ │
│    │    - 일부 복잡한 명령어 추가 (SIMD, 암호화 등)                   │ │
│    │    - 데스크톱/서버 시장 진출 (Apple M1, AWS Graviton)            │ │
│    └─────────────────────────────────────────────────────────────────┘ │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

3. 명령어 형식

3.1 MIPS 명령어 형식

┌─────────────────────────────────────────────────────────────────────────┐
                         MIPS 명령어 형식 (32비트)                        
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
                            R-type (레지스터)                         
                                                                      
       31    26 25   21 20   16 15   11 10    6 5      0             
       ┌──────┬───────┬───────┬───────┬───────┬────────┐             
       opcode  rs     rt     rd    shamt  funct               
       6 bits5 bits 5 bits 5 bits 5 bits 6 bits               
       └──────┴───────┴───────┴───────┴───────┴────────┘             
                                                                      
       : ADD $rd, $rs, $rt                                          
           opcode=0, funct=0x20 (add)                                 
           rd = rs + rt                                               
                                                                      
       : SLL $rd, $rt, shamt                                        
           rd = rt << shamt                                           
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
                            I-type (즉시값)                           
                                                                      
       31    26 25   21 20   16 15                  0                
       ┌──────┬───────┬───────┬─────────────────────┐                
       opcode  rs     rt       immediate                        
       6 bits5 bits 5 bits      16 bits                         
       └──────┴───────┴───────┴─────────────────────┘                
                                                                      
       : ADDI $rt, $rs, imm                                         
           rt = rs + sign_extend(imm)                                 
                                                                      
       : LW $rt, offset($rs)                                        
           rt = Memory[rs + sign_extend(offset)]                      
                                                                      
       : BEQ $rs, $rt, offset                                       
           if (rs == rt) PC = PC + 4 + offset * 4                     
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
                            J-type (점프)                             
                                                                      
       31    26 25                                 0                 
       ┌──────┬─────────────────────────────────────┐                
       opcode              address                                
       6 bits              26 bits                                
       └──────┴─────────────────────────────────────┘                
                                                                      
       : J target                                                   
           PC = (PC[31:28] << 28) | (address << 2)                    
                                                                      
       : JAL target                                                 
           $ra = PC + 4; PC = target                                 
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

3.2 MIPS 명령어 인코딩 예시

┌─────────────────────────────────────────────────────────────────────────┐
                      MIPS 명령어 인코딩 예시                             
                                                                         
    예시 1: ADD $t0, $s1, $s2                                            
    ────────────────────────────────────────────────                     
    R-type: rd = rs + rt                                                 
    $t0 = 8, $s1 = 17, $s2 = 18                                          
                                                                         
    ┌──────┬───────┬───────┬───────┬───────┬────────┐                   
    000000 10001  10010  01000  00000  100000                    
      op    rs     rt     rd    shamt  funct                     
      =0   =$s1   =$s2   =$t0    =0    =add                      
    └──────┴───────┴───────┴───────┴───────┴────────┘                   
    = 0x02324020                                                         
                                                                         
    예시 2: LW $t0, 100($s0)                                             
    ────────────────────────────────────────────────                     
    I-type: rt = Memory[rs + offset]                                     
    $t0 = 8, $s0 = 16, offset = 100                                      
                                                                         
    ┌──────┬───────┬───────┬─────────────────────┐                      
    100011 10000  01000  0000000001100100                          
      op    rs     rt       immediate                              
     =lw   =$s0   =$t0        =100                                 
    └──────┴───────┴───────┴─────────────────────┘                      
    = 0x8E080064                                                         
                                                                         
    예시 3: BEQ $s0, $s1, loop  (loop가 8바이트 )                       
    ────────────────────────────────────────────────                     
    I-type: if (rs == rt) PC = PC + 4 + offset*4                         
    offset = (loop - PC - 4) / 4 = 2                                     
                                                                         
    ┌──────┬───────┬───────┬─────────────────────┐                      
    000100 10000  10001  0000000000000010                          
      op    rs     rt       offset                                 
     =beq  =$s0   =$s1        =2                                   
    └──────┴───────┴───────┴─────────────────────┘                      
    = 0x12110002                                                         
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

3.3 ARM 명령어 형식

┌─────────────────────────────────────────────────────────────────────────┐
                       ARM 명령어 형식 (32비트)                           
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
                        Data Processing (데이터 처리)                  
                                                                      
       31  28 27 26 25 24   21 20 19  16 15  12 11           0       
       ┌────┬─────┬──┬───────┬──┬──────┬──────┬───────────────┐      
       cond 00  I opcode S   Rn    Rd     Operand2          
       4bit2bit 1  4bit  1  4bit  4bit     12bit            
       └────┴─────┴──┴───────┴──┴──────┴──────┴───────────────┘      
                                                                      
       cond: 조건 코드 (EQ, NE, GT, LT )                            
       I: 즉시값 여부                                                 
       S: 플래그 업데이트 여부                                        
                                                                      
       : ADD R0, R1, R2                                             
           Rd = Rn + Operand2                                         
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
                     Load/Store (메모리 접근)                          
                                                                      
       31  28 27 26 25 24 23 22 21 20 19  16 15  12 11         0     
       ┌────┬─────┬──┬──┬──┬──┬──┬──┬──────┬──────┬─────────────┐    
       cond 01  I P U B W L   Rn    Rd     offset        
       4bit2bit 1 1 1 1 1 1  4bit  4bit    12bit         
       └────┴─────┴──┴──┴──┴──┴──┴──┴──────┴──────┴─────────────┘    
                                                                      
       P: Pre/Post 인덱싱                                             
       U: Up/Down (더하기/빼기)                                       
       B: Byte/Word                                                   
       W: Write-back                                                  
       L: Load/Store                                                  
                                                                      
       : LDR R0, [R1, #100]                                         
           R0 = Memory[R1 + 100]                                      
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
                          Branch (분기)                                
                                                                      
       31  28 27  25 24 23                            0              
       ┌────┬───────┬──┬──────────────────────────────┐              
       cond  101  L           offset                            
       4bit 3bit  1           24bit                             
       └────┴───────┴──┴──────────────────────────────┘              
                                                                      
       L: Link (BL이면 1, LR에 복귀 주소 저장)                        
       offset: PC-relative offset (<<2  부호 확장)                  
                                                                      
       : BL function                                                
           LR = PC + 4; PC = PC + offset << 2                         
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

3.4 x86 명령어 형식

┌─────────────────────────────────────────────────────────────────────────┐
│                     x86 명령어 형식 (가변 길이)                          │
│                                                                         │
│    ┌──────┬───────┬─────────┬────────┬─────────────┬───────────────┐   │
│    │Prefix│Opcode │ ModR/M  │  SIB   │Displacement │  Immediate    │   │
│    │0-4   │1-3    │ 0-1     │ 0-1    │   0,1,2,4   │  0,1,2,4      │   │
│    │bytes │bytes  │ byte    │ byte   │   bytes     │  bytes        │   │
│    └──────┴───────┴─────────┴────────┴─────────────┴───────────────┘   │
│                                                                         │
│    ModR/M 바이트 (피연산자 지정):                                        │
│    ┌────────┬───────┬───────┐                                          │
│    │  Mod   │  Reg  │  R/M  │                                          │
│    │ 2 bits │3 bits │3 bits │                                          │
│    └────────┴───────┴───────┘                                          │
│                                                                         │
│    SIB 바이트 (복잡한 주소 계산):                                        │
│    ┌────────┬───────┬───────┐                                          │
│    │ Scale  │ Index │ Base  │                                          │
│    │ 2 bits │3 bits │3 bits │                                          │
│    └────────┴───────┴───────┘                                          │
│    Address = Base + Index * Scale + Displacement                        │
│                                                                         │
│    예시:                                                                │
│    ┌─────────────────────────────────────────────────────────────────┐ │
│    │ MOV EAX, [EBX+ECX*4+100]                                        │ │
│    │                                                                 │ │
│    │ ┌────────┬─────────┬─────────┬──────────────┐                   │ │
│    │ │ 8B     │ 84      │ 8B      │ 64 00 00 00  │                   │ │
│    │ │ Opcode │ ModR/M  │ SIB     │ Displacement │                   │ │
│    │ │        │Mod=10   │Scale=4  │ =100         │                   │ │
│    │ │        │Reg=EAX  │Index=ECX│              │                   │ │
│    │ │        │R/M=100  │Base=EBX │              │                   │ │
│    │ └────────┴─────────┴─────────┴──────────────┘                   │ │
│    │ 총 7 바이트                                                     │ │
│    └─────────────────────────────────────────────────────────────────┘ │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

4. 주소 지정 방식

4.1 주소 지정 방식 개요

┌─────────────────────────────────────────────────────────────────────────┐
│                        주소 지정 방식 종류                               │
│                                                                         │
│    ┌─────────────────────────────────────────────────────────────────┐ │
│    │  1. 즉시 주소 지정 (Immediate Addressing)                       │ │
│    │                                                                 │ │
│    │     명령어: ADDI $t0, $t1, 100                                  │ │
│    │                                                                 │ │
│    │     ┌────────┬───────────────────────────────┐                  │ │
│    │     │ Opcode │  ... │ 100 (Immediate Value) │                  │ │
│    │     └────────┴─────────────────┬─────────────┘                  │ │
│    │                                │                                │ │
│    │                                ▼                                │ │
│    │                           피연산자                               │ │
│    │                                                                 │ │
│    │     피연산자가 명령어 안에 포함됨                                │ │
│    │     빠름, 상수 사용에 적합                                      │ │
│    └─────────────────────────────────────────────────────────────────┘ │
│                                                                         │
│    ┌─────────────────────────────────────────────────────────────────┐ │
│    │  2. 레지스터 주소 지정 (Register Addressing)                    │ │
│    │                                                                 │ │
│    │     명령어: ADD $t0, $t1, $t2                                   │ │
│    │                                                                 │ │
│    │     ┌────────┬──────┬──────┬──────┐                             │ │
│    │     │ Opcode │ $t1  │ $t2  │ $t0  │                             │ │
│    │     └────────┴───┬──┴───┬──┴──────┘                             │ │
│    │                  │      │                                       │ │
│    │                  ▼      ▼                                       │ │
│    │            ┌──────────────────┐                                 │ │
│    │            │  레지스터 파일   │                                 │ │
│    │            │  ┌────┬────┬───┐│                                 │ │
│    │            │  │$t1 │$t2 │...││                                 │ │
│    │            │  └──┬─┴──┬─┴───┘│                                 │ │
│    │            └─────┼────┼──────┘                                 │ │
│    │                  ▼    ▼                                        │ │
│    │               피연산자들                                         │ │
│    │                                                                 │ │
│    │     레지스터 번호가 피연산자 지정                                │ │
│    │     가장 빠름 (레지스터 접근)                                   │ │
│    └─────────────────────────────────────────────────────────────────┘ │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

4.2 메모리 주소 지정 방식

┌─────────────────────────────────────────────────────────────────────────┐
                      메모리 주소 지정 방식                               
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
      3. 직접 주소 지정 (Direct Addressing)                           
                                                                      
         명령어: LOAD R1, 0x1000                                      
                                                                      
         ┌────────┬──────────────────────┐                            
          Opcode  Address: 0x1000                                  
         └────────┴──────────┬───────────┘                            
                                                                     
                                                                     
                   ┌─────────────────┐                                
                        메모리                                      
                     0x1000: [데이터] ───► 피연산자                  
                   └─────────────────┘                                
                                                                      
         주소가 명령어에 직접 포함                                    
         전역 변수 접근에 사용                                        
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
      4. 간접 주소 지정 (Indirect Addressing)                         
                                                                      
         명령어: LOAD R1, (0x1000)                                    
                                                                      
         ┌────────┬──────────────────────┐                            
          Opcode  Address: 0x1000                                  
         └────────┴──────────┬───────────┘                            
                                                                     
                                                                     
                   ┌─────────────────┐                                
                        메모리                                      
                     0x1000: 0x2000  ─┐                             
                     0x2000: [데이터]│◄┘ ───► 피연산자               
                   └─────────────────┘                                
                                                                      
         메모리에서 실제 주소를 읽어옴                                 
         포인터, 동적 데이터 구조에 사용                               
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
      5. 레지스터 간접 주소 지정 (Register Indirect)                  
                                                                      
         명령어: LW $t0, ($s0)   ; MIPS                               
         명령어: MOV EAX, [EBX]  ; x86                                
                                                                      
         ┌────────┬───────┐                                           
          Opcode   $s0                                             
         └────────┴───┬───┘                                           
                                                                     
                                                                     
             ┌──────────────┐                                         
              $s0 = 0x1000                                          
             └──────┬───────┘                                         
                                                                     
                                                                     
             ┌─────────────────┐                                      
                  메모리                                            
              0x1000: [데이터] ───► 피연산자                        
             └─────────────────┘                                      
                                                                      
         레지스터가 메모리 주소를 담고 있음                            
         포인터 역참조에 사용                                         
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

4.3 변위 주소 지정

┌─────────────────────────────────────────────────────────────────────────┐
                       변위 주소 지정 방식                                
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
      6. 변위/베이스 주소 지정 (Displacement/Base Addressing)         
                                                                      
         명령어: LW $t0, 100($s0)   ; MIPS                            
         명령어: MOV EAX, [EBX+100] ; x86                             
                                                                      
         ┌────────┬───────┬───────────┐                               
          Opcode   $s0   offset=100                               
         └────────┴───┬───┴─────┬─────┘                               
                                                                    
                                                                    
             ┌──────────────┐                                        
              $s0 = 0x1000                                         
             └──────┬───────┘                                        
                                                                    
                    └─────┬─────┘                                     
                           + (주소 계산)                             
                                                                     
                  유효 주소 = 0x1064                                   
                                                                     
                                                                     
             ┌─────────────────┐                                      
                  메모리                                            
              0x1064: [데이터] ───► 피연산자                        
             └─────────────────┘                                      
                                                                      
         베이스 레지스터 + 변위로 주소 계산                            
         배열, 구조체 접근에 사용                                     
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
      7. 인덱스 주소 지정 (Indexed Addressing)                        
                                                                      
         명령어: MOV EAX, [EBX + ECX*4 + 100] ; x86                   
                                                                      
         유효 주소 = Base + Index × Scale + Displacement              
                   = EBX + ECX × 4 + 100                              
                                                                      
         ┌────────────────────────────────────────┐                   
                                                                    
            EBX (베이스) ──────────┐                                
                                                                  
            ECX (인덱스) ─► × 4 ──┤                                
                                   + ──► 유효 주소                 
            100 (변위) ───────────┘                                
                                                                    
         └────────────────────────────────────────┘                   
                                                                      
         배열 요소 접근에 최적화                                      
         : array[i] = arr_base + i * sizeof(element)                
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

4.4 PC 상대 주소 지정

┌─────────────────────────────────────────────────────────────────────────┐
│                       PC 상대 주소 지정                                  │
│                                                                         │
│    ┌─────────────────────────────────────────────────────────────────┐ │
│    │  8. PC 상대 주소 지정 (PC-Relative Addressing)                  │ │
│    │                                                                 │ │
│    │     명령어: BEQ $t0, $t1, label                                 │ │
│    │                                                                 │ │
│    │     유효 주소 = PC + offset × 4                                 │ │
│    │                                                                 │ │
│    │     ┌────────┬───────┬───────┬───────────────┐                  │ │
│    │     │ Opcode │  $t0  │  $t1  │ offset = 3    │                  │ │
│    │     └────────┴───────┴───────┴───────┬───────┘                  │ │
│    │                                      │                          │ │
│    │     메모리 레이아웃:                 │                          │ │
│    │     ┌─────────────────────────────┐  │                          │ │
│    │     │ 0x1000: BEQ ...        ◄─── PC (현재)                     │ │
│    │     │ 0x1004: ...                │                              │ │
│    │     │ 0x1008: ...                │                              │ │
│    │     │ 0x100C: ...                │                              │ │
│    │     │ 0x1010: label:        ◄─── PC + 4 + 3×4 = 0x1010         │ │
│    │     └─────────────────────────────┘                             │ │
│    │                                                                 │ │
│    │     분기 명령어에 주로 사용                                     │ │
│    │     위치 독립적 코드 (PIC) 지원                                 │ │
│    └─────────────────────────────────────────────────────────────────┘ │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

4.5 주소 지정 방식 비교

방식 유효 주소 장점 단점 용도
즉시 없음 (값 자체) 빠름 값 크기 제한 상수
레지스터 레지스터 가장 빠름 레지스터 수 제한 임시 변수
직접 명령어 내 주소 단순 주소 크기 제한 전역 변수
간접 Mem[주소] 유연 메모리 접근 2번 포인터
레지스터 간접 Reg 유연 - 포인터 역참조
변위 Reg + offset 배열 접근 - 구조체/배열
인덱스 Base + Idx×S + D 배열 최적화 복잡 배열[i]
PC 상대 PC + offset PIC 지원 범위 제한 분기

5. 대표적인 ISA

5.1 x86 / x86-64

┌─────────────────────────────────────────────────────────────────────────┐
                           x86 / x86-64                                   
                                                                         
    역사:                                                                
    ┌─────────────────────────────────────────────────────────────────┐ 
      1978: 8086 (16비트)                                             
      1985: 80386 (32비트, IA-32)                                     
      2003: x86-64 / AMD64 (64비트)                                   
      현재: 수십억 대의 PC/서버에서 사용                               
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    레지스터 (x86-64):                                                   
    ┌─────────────────────────────────────────────────────────────────┐ 
      범용 레지스터 (16):                                           
      RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, R8-R15                 
                                                                      
      특수 레지스터:                                                  
      RIP (Instruction Pointer), RFLAGS (상태 플래그)                
                                                                      
      세그먼트 레지스터:                                              
      CS, DS, SS, ES, FS, GS                                         
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    대표 명령어:                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
      ; 데이터 이동                                                   
      MOV EAX, EBX          ; EAX = EBX                              
      MOV EAX, [EBX]        ; EAX = Memory[EBX]                      
      MOV EAX, [EBX+ECX*4]  ; 배열 접근                              
                                                                      
      ; 산술 연산                                                     
      ADD EAX, EBX          ; EAX = EAX + EBX                        
      SUB EAX, 10           ; EAX = EAX - 10                         
      IMUL EAX, EBX         ; EAX = EAX * EBX                        
                                                                      
      ; 분기                                                          
      CMP EAX, EBX          ; 비교 (플래그 설정)                      
      JE  label             ; Equal이면 점프                         
      JNE label             ; Not Equal이면 점프                     
      JMP label             ; 무조건 점프                            
                                                                      
      ; 함수 호출                                                     
      CALL function         ; 함수 호출                              
      RET                   ; 반환                                   
      PUSH EAX              ; 스택에 푸시                            
      POP  EBX              ; 스택에서                             
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

5.2 ARM

┌─────────────────────────────────────────────────────────────────────────┐
                               ARM                                        
                                                                         
    역사:                                                                
    ┌─────────────────────────────────────────────────────────────────┐ 
      1985: ARM1 (32비트 RISC)                                        
      2011: ARMv8 (64비트, AArch64)                                   
      현재: 스마트폰, 태블릿, IoT, 서버 (Apple M1/M2, AWS Graviton)  
      특징: 저전력, 라이선스 기반 비즈니스                             
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    레지스터 (AArch64):                                                  
    ┌─────────────────────────────────────────────────────────────────┐ 
      범용 레지스터 (31):                                           
      X0-X30 (64비트), W0-W30 (하위 32비트)                          
                                                                      
      특수 레지스터:                                                  
      SP (Stack Pointer), PC (Program Counter)                       
      X30/LR (Link Register)                                         
      XZR/WZR (Zero Register)                                        
                                                                      
      시스템 레지스터:                                                
      NZCV (조건 플래그), FPCR, FPSR                                 
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    대표 명령어 (AArch64):                                               
    ┌─────────────────────────────────────────────────────────────────┐ 
      ; 데이터 이동                                                   
      MOV  X0, X1           ; X0 = X1                                
      LDR  X0, [X1]         ; X0 = Memory[X1]                        
      STR  X0, [X1, #8]     ; Memory[X1+8] = X0                      
                                                                      
      ; 산술 연산                                                     
      ADD  X0, X1, X2       ; X0 = X1 + X2                           
      SUB  X0, X1, #10      ; X0 = X1 - 10                           
      MUL  X0, X1, X2       ; X0 = X1 * X2                           
                                                                      
      ; 비교  분기                                                  
      CMP  X0, X1           ; X0 - X1 (플래그 설정)                   
      B.EQ label            ; Equal이면 분기                         
      B.NE label            ; Not Equal이면 분기                     
      B    label            ; 무조건 분기                            
                                                                      
      ; 함수 호출                                                     
      BL   function         ; Branch with Link (LR에 복귀주소)       
      RET                   ; Return (LR로 점프)                     
                                                                      
      ; 조건부 실행 (ARM32)                                           
      ADDEQ R0, R1, R2      ; Equal이면 ADD 실행                     
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    특징:                                                                
    - 조건부 실행 (대부분의 명령어에 조건 접미사)                        
    - Load/Store 아키텍처                                                
    - Thumb 명령어 세트 (16비트, 코드 밀도 향상)                         
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

5.3 MIPS

┌─────────────────────────────────────────────────────────────────────────┐
                               MIPS                                       
                                                                         
    역사  특징:                                                        
    ┌─────────────────────────────────────────────────────────────────┐ 
      1985: MIPS R2000 (순수 RISC 설계)                               
      특징: 학술적으로 중요 (컴퓨터 구조 교육의 표준)                  
      용도: 임베디드 시스템, 네트워크 장비, 게임 콘솔 (PS1/2)         
      2021: MIPS Technologies가 RISC-V로 전환                         
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    레지스터 (32):                                                     
    ┌─────────────────────────────────────────────────────────────────┐ 
      $zero (R0)  : 항상 0                                           
      $at   (R1)  : 어셈블러 임시                                    
      $v0-v1 (R2-3): 함수 반환값                                     
      $a0-a3 (R4-7): 함수 인자                                       
      $t0-t7 (R8-15): 임시 (caller-saved)                            
      $s0-s7 (R16-23): 저장 (callee-saved)                           
      $t8-t9 (R24-25): 추가 임시                                     
      $gp   (R28) : 전역 포인터                                      
      $sp   (R29) : 스택 포인터                                      
      $fp   (R30) : 프레임 포인터                                    
      $ra   (R31) : 반환 주소                                        
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    대표 명령어:                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
      ; R-type (레지스터)                                             
      add  $t0, $t1, $t2    ; $t0 = $t1 + $t2                        
      sub  $t0, $t1, $t2    ; $t0 = $t1 - $t2                        
      and  $t0, $t1, $t2    ; $t0 = $t1 & $t2                        
      sll  $t0, $t1, 2      ; $t0 = $t1 << 2                         
                                                                      
      ; I-type (즉시값)                                               
      addi $t0, $t1, 100    ; $t0 = $t1 + 100                        
      lw   $t0, 4($sp)      ; $t0 = Memory[$sp + 4]                  
      sw   $t0, 0($sp)      ; Memory[$sp] = $t0                      
      beq  $t0, $t1, label  ; if ($t0 == $t1) goto label             
      bne  $t0, $t1, label  ; if ($t0 != $t1) goto label             
                                                                      
      ; J-type (점프)                                                 
      j    target           ; goto target                            
      jal  function         ; $ra = PC+4; goto function              
      jr   $ra              ; goto $ra (함수 반환)                   
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

5.4 RISC-V

┌─────────────────────────────────────────────────────────────────────────┐
                              RISC-V                                      
                                                                         
    역사  특징:                                                        
    ┌─────────────────────────────────────────────────────────────────┐ 
      2010: UC Berkeley에서 개발 시작                                 
      특징:                                                           
      - 오픈소스 ISA (로열티 프리)                                    
      - 모듈식 설계 (기본 + 확장)                                     
      - 학술  산업계에서 빠르게 채택                                
      - 32/64/128비트 지원                                           
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    모듈식 구조:                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
      RV32I / RV64I: 기본 정수 명령어 (필수)                          
      M: 곱셈/나눗셈 확장                                             
      A: 원자적 연산 확장                                             
      F: 단정밀도 부동소수점                                          
      D: 배정밀도 부동소수점                                          
      C: 압축 명령어 (16비트)                                         
                                                                      
      : RV64IMAFDC = 64비트 + 모든 표준 확장                        
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    레지스터 (32):                                                     
    ┌─────────────────────────────────────────────────────────────────┐ 
      x0 (zero): 항상 0                                              
      x1 (ra)  : 반환 주소                                           
      x2 (sp)  : 스택 포인터                                         
      x3 (gp)  : 전역 포인터                                         
      x4 (tp)  : 스레드 포인터                                       
      x5-x7    : 임시                                                
      x8 (s0/fp): 저장/프레임 포인터                                 
      x9       : 저장                                                
      x10-x17  : 함수 인자/반환                                      
      x18-x27  : 저장                                                
      x28-x31  : 임시                                                
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
    대표 명령어:                                                         
    ┌─────────────────────────────────────────────────────────────────┐ 
      ; R-type                                                        
      add  x1, x2, x3       ; x1 = x2 + x3                           
      sub  x1, x2, x3       ; x1 = x2 - x3                           
                                                                      
      ; I-type                                                        
      addi x1, x2, 100      ; x1 = x2 + 100                          
      lw   x1, 0(x2)        ; x1 = Memory[x2]                        
                                                                      
      ; S-type (Store)                                                
      sw   x1, 0(x2)        ; Memory[x2] = x1                        
                                                                      
      ; B-type (Branch)                                               
      beq  x1, x2, label    ; if (x1 == x2) goto label               
      bne  x1, x2, label    ; if (x1 != x2) goto label               
                                                                      
      ; J-type                                                        
      jal  x1, target       ; x1 = PC+4; goto target                 
      jalr x1, x2, 0        ; x1 = PC+4; goto x2                     
    └─────────────────────────────────────────────────────────────────┘ 
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

5.5 ISA 비교 요약

┌─────────────────────────────────────────────────────────────────────────────┐
│                           ISA 비교 요약                                      │
├──────────────┬──────────────┬──────────────┬──────────────┬────────────────┤
│    특성      │    x86-64    │     ARM      │     MIPS     │    RISC-V      │
├──────────────┼──────────────┼──────────────┼──────────────┼────────────────┤
│ 종류         │ CISC         │ RISC         │ RISC         │ RISC           │
├──────────────┼──────────────┼──────────────┼──────────────┼────────────────┤
│ 명령어 길이  │ 1-15 바이트  │ 4 바이트     │ 4 바이트     │ 4 바이트       │
│              │ (가변)       │ (고정)       │ (고정)       │ (2/4 바이트)   │
├──────────────┼──────────────┼──────────────┼──────────────┼────────────────┤
│ 범용 레지스터│ 16개         │ 31개         │ 32개         │ 32개           │
├──────────────┼──────────────┼──────────────┼──────────────┼────────────────┤
│ 엔디안       │ Little       │ Bi-endian    │ Bi-endian    │ Little         │
├──────────────┼──────────────┼──────────────┼──────────────┼────────────────┤
│ 주요 용도    │ PC, 서버     │ 모바일, IoT  │ 임베디드     │ 범용, 교육     │
│              │              │ 서버 (최근)  │ (레거시)     │ IoT            │
├──────────────┼──────────────┼──────────────┼──────────────┼────────────────┤
│ 라이선스     │ Intel/AMD    │ ARM Holdings │ MIPS Tech.   │ 오픈소스       │
│              │ 독점         │ 라이선스     │ 라이선스     │ (무료)         │
└──────────────┴──────────────┴──────────────┴──────────────┴────────────────┘

6. 연습 문제

기초 문제

  1. ISA가 정의하는 것들 5가지를 나열하시오.

  2. CISC와 RISC의 주요 차이점 3가지를 설명하시오.

  3. MIPS의 세 가지 명령어 형식(R, I, J)을 설명하시오.

명령어 인코딩 문제

  1. 다음 MIPS 명령어를 32비트 이진수로 인코딩하시오: ADD $t2, $s0, $s1 (참고: $t2=10, $s0=16, $s1=17, ADD의 funct=0x20)

  2. 다음 MIPS 명령어를 32비트 이진수로 인코딩하시오: LW $t0, 200($s2) (참고: $t0=8, $s2=18, LW의 opcode=0x23)

주소 지정 방식 문제

  1. 다음 각 명령어의 주소 지정 방식을 식별하시오:
  2. (a) ADDI $t0, $t1, 100
  3. (b) LW $t0, 0($s0)
  4. (c) ADD $t0, $t1, $t2
  5. (d) J 0x00400000
  6. (e) BEQ $t0, $t1, label

  7. x86에서 MOV EAX, [EBX + ECX*4 + 100]의 유효 주소 계산 방식을 설명하시오.

심화 문제

  1. 현대 x86 프로세서가 내부적으로 RISC 스타일의 micro-ops를 사용하는 이유를 설명하시오.

  2. RISC-V가 오픈소스 ISA로서 갖는 장점을 3가지 설명하시오.

  3. 다음 C 코드를 MIPS 어셈블리로 변환하시오: c int a = 10; int b = 20; int c = a + b;

정답 1. ISA가 정의하는 것: - 명령어 집합 (Instructions) - 레지스터 (Registers) - 데이터 타입 (Data Types) - 주소 지정 방식 (Addressing Modes) - 메모리 모델 (Memory Model) 2. CISC vs RISC: - 명령어 복잡도: CISC는 복잡, RISC는 단순 - 명령어 길이: CISC는 가변, RISC는 고정 - 메모리 접근: CISC는 모든 명령어에서 가능, RISC는 Load/Store만 3. MIPS 명령어 형식: - R-type: 레지스터 간 연산 (ADD, SUB 등) - I-type: 즉시값 사용 (ADDI, LW, SW, BEQ 등) - J-type: 점프 명령어 (J, JAL) 4. ADD $t2, $s0, $s1 인코딩: ``` opcode(6) | rs(5) | rt(5) | rd(5) | shamt(5) | funct(6) 000000 | 10000 | 10001 | 01010 | 00000 | 100000 = 0x02115020 ``` 5. LW $t0, 200($s2) 인코딩: ``` opcode(6) | rs(5) | rt(5) | immediate(16) 100011 | 10010 | 01000 | 0000000011001000 = 0x8E4800C8 ``` 6. 주소 지정 방식: - (a) 즉시 주소 지정 (Immediate) - (b) 레지스터 간접 + 변위 (Base/Displacement) - (c) 레지스터 주소 지정 (Register) - (d) 직접 주소 지정 (Direct) - (e) PC 상대 주소 지정 (PC-Relative) 7. x86 유효 주소 계산: 유효 주소 = Base(EBX) + Index(ECX) × Scale(4) + Displacement(100) 8. micro-ops 사용 이유: - 파이프라이닝 최적화 (RISC 스타일의 간단한 명령어) - 슈퍼스칼라 실행 용이 - 비순차 실행 구현 용이 - 후방 호환성 유지하면서 내부 최적화 9. RISC-V 오픈소스 장점: - 로열티 무료 (비용 절감) - 커스터마이징 가능 (특정 용도에 최적화) - 학술 연구 및 교육에 유용 - 벤더 종속성 없음 10. C 코드의 MIPS 변환: ```mips # a = 10 li $s0, 10 # $s0 = 10 # b = 20 li $s1, 20 # $s1 = 20 # c = a + b add $s2, $s0, $s1 # $s2 = $s0 + $s1 ```

다음 단계


참고 자료

to navigate between lessons