leehyeon-dv 님의 블로그

2.8 Supporting Procedures in Computer Hardware 본문

컴퓨터구조 및 설계/2장. language of the computer

2.8 Supporting Procedures in Computer Hardware

leehyeon-dv 2024. 11. 16. 20:07

🔑Table of Contents

  1. 6 Steps in Execution of a Producedure       - 프로시저(함수) 실행의 6단계
  2. Register Usage                                            
  3. Procedure Call Instructions                         
  4. Leaf Procedure 예제
  5.  None-Leaf Procedures                               - 프로시저 내에서 다른 프로시저 호출
  6. Local Data on the Stack                              - 프로그램에서 프로시저가 호출될때 메모리할당
  7. Memory Layout
  8. 궁금한점

📌6 Steps in Execution of a Producedure

  1. 메인 루틴(Caller)이 파라미터(매개값)을 프로시저(callee)가 접근가능한 곳에 위치시킨다
  2. caller가 제어권을 callee에게 넘겨준다
  3. callee는 필요한 storage(메모리)를 얻는다 
  4. callee는 요구되는 일을 수행한다
  5. callee는 결과값을 caller가 접근가능한 곳에 위치시킨다
  6. callee는 제어권을 caller에게 반납한다

📌Register Usage

💡숫자 기억해두기 28~31까지(용도에 맞는 사용을 할 수 있다)

임시레지스터 -> 호출자에 의해 오버라이트 할수있다

 

📌Procedure Call Instructions

  • 프로시저 호출 : jal (jump and link)  ※그냥 점프는  j
    •  Jal Procedure Label
      • 바로 다음에 올 instruction의 주소를 $ra에 담는다(프로시저가 종료되면 다음으로 진행되기 위해)
      • 대상주소(프로시저가 수행되기위해 label된)로 점프
  • 프로시저 리턴 : jr (jump register)
    • Jr $ra 
      • 프로그램 카운터(PC)에 $ra을 복사한다(즉, 프로시저 다음의 명령 주소로 돌아와 계속 진행하려는것)
      • computed jump에 사용될수있음(특정 주소로 가는것(Jr $t0))

📌Leaf Procedure 예제

Leaf Procedure : 함수내에서 다른 함수를 호출하지 않음

* C code:

int leaf_example(int g,h,i,j){
    int f;
    f = (g+h)-(i+j);
    return f; }
    
//g,h,i,j -> $a0,$a1,$a2,$a3, f->$s0, 반환값 ->$v0

 

* MIPS code:

💡빈칸문제 낼수있음💡

leaf_example:
    addi $sp, $sp, -4    //4만큼 스택포인터 이동(스택 공간확보)
    sw   $s0, 0($sp)     //$s0의 값을 $sp에 저장
    add  $t0, $a0, $a1   //Procedure body
    add  $t1, $a2, $a3
    sub  $s0, $t0, $t1
    add  $v0, $s0, $zero //MIPS는 MOV가 없어 $zero의 add로 처리
    lw   $s0, 0($sp)     //$sp에서 $s0의 값 복구
    addi $sp, $sp, 4     //4만큼 스택포인터 복귀
    jr   $ra             //$ra로 점프 (호출자에게 반환)

 

📌 None-Leaf Procedures

  • 프로시저 내에서 다른 프로시저를 호출하는 형태
  • 내포된(nest된) 호출이 있으므로 caller는 스택에 다음값들을 저장해야한다
    • 반환된 주소 (Leaf와 다르게 $ra 하나에 의존할수없기에)
    • 필요한 매개값이나 임시 값들
  • call 이후에(한 루틴이 끝나면) 스택에 저장해둔 값을 복귀시켜야한다

* C code:

int fact(int n){
    if (n<1) return 1;
    else return n*fact(n-1); }

//매개변수 n -> $a0,  반환값 -> $v0

 

* MIPS code:

fact :
    addi $sp, $sp, -8     //스택공간확보(2개를 위한)
    sw   $ra, 4($sp)      //$ra 스택에 저장
    sw   $a0, 0($sp)      //$a0 스택에 저장
    slti $t0, $a0, 1      
    beq  $t0, $zero, L1   //a0>=1일경우 L1으로
    addi $v0, $zero, 1    
    addi $sp, $sp, 8
    jr   $ra
L1 :
    addi $a0, $a0, -1     //재귀호출준비(n-1)
    jal  fact             // 재귀호출
    lw   $a0, 0($sp)      //스택에서 백업된 $a0값 복구 
    lw   $ra, 4($sp)      //스택에서 백업된 $ra값 복구
    addi $sp, $sp, 8
    mul  $v0, $a0, $v0    //n * fact(n-1)
    jr   $ra

 

📌 Local Data on the Stack

프로그램에서 프로시저(function)가 호출 될 때 메모리가 어떻게 할당되는지

  • $sp는 스택의 top을 가리키고
  • $fp(frame pointer)는 현재 함수의 시작 시점의 스택 위치 (함수가 실행될때 스택포인터 위치를 저장해, 종료시 위치복구에 사용)
  • procedure frame (activation record)
    • $fp에서 $sp까지 영역. 함수가 실행되는 동안 스택에 할당되는 메모리영역
    • 몇몇 컴파일러들은 스택 공간을 관리하기 위해 사용한다
  • local data는 callee에 의해 할당된다 (함수시작시 스택에서 필요한 공간확보한다는말)

📌 Memory Layout

프로그램과 데이터를 위한 MIPS 메모리 할당

  • Text : 프로그램 코드 (instruction들)    #pc가 이 영역에서 움직이면서 현재 실행될 instruction을 가리킨다
  • Static data : 전역변수들
    • C에서 전역변수 : static, constant array, string..
    • $gp(global pointer)
      • static data를 가리키기 쉽게 static data와 Dynamic data영역 사이에 위치
      • ±offset으로 데이터를 가리켜준다 (MIPS에서는 중간 다른 프로세서는 다르게 동작할 수도 있음)
      •  전역변수,상수,정적데이터가 저장된
  • Dynamic data : 힙 메모리로, 동적으로 할당된 메모리가 저장됨
    • c에서 malloc, java에서 new ...
  • Stack : 현재 영역에서 사용할 자료 및 복귀 주소 등 (activation record들이 쌓였다 복구됨)

 

📍?<궁금한점>📍

🔎caller/ callee의 의미

 

  • Caller: 함수를 호출하는 쪽, 즉 메인 루틴이나 다른 함수입니다.
  • Callee: 호출된 함수 자신을 의미합니다.
int sum(int a, int b) { return a + b;}  // Callee (호출된 함수)

int main() {   // Caller (호출하는 함수)
    int result = sum(10, 20); 
    printf("Result: %d\n", result);
    return 0;
}

 

🔎"임시레지스터는 호출자에 의해 오버라이트할 수 있다"의 의미

  • 임시 레지스터는 함수 호출시 caller가 사용하고, 값을 보존할 필요가 없다
  • 만약 callee에서 임시 레지스터를 사용하고 있으면, caller가 임시레지스터를 덮어쓰면서 기존 값이 사라질 수 있다

 

🔎 PC란?

현재 실행하고 있는 명령의 메모리 주소가 담기는 레지스터

 

🔎스택포인터

MIPS 어셈블리어에서 스택의 현재위치를 가리키는 레지스터

(스택 = 메모리의 특정영역, 함수 호출시 임시 데이터를 저장하거나 복구하는데 사용)

  • MIPS에서는 스택이 메모리의 주소에서 낮은 주소로 성장한다
    • 즉, 스택에 데이터를 추가(push)하면 스택 포인터가 감소합니다.
    • 스택에서 데이터를 꺼내(pop)면 스택 포인터가 증가합니다.

🔎 ±offset

MIPS 어셈블리에서 $gp나 $fp를 사용해 메모리 주소에 접근시 사용되는 상대적인 거리

 

🔎힙 메모리

  • 동적할당 : 프로그램 실행 중 사용자가 필요한 만큼 메모리 할당 가능
  • 명시적 해제필요 : c언어에서는 malloc()으로 메모리를 할당해 free()로 해제
  • 비정렬 메모리 영역 : 힙 메모리는 정해진 순서 없이 여러 위치에서 할당되고 해제되기에 단편화가 발생할 수 있