컴퓨터아키텍처

Computer Architecture

2016-03-30


MIPS 함수 호출과 스택 사용
 

과제 제출 안내

  • Google Drive 공유 폴더를 통해 (종이 X, 메일 X)
  • [새로 만들기] 버튼을 눌러
    CA16<이름><학번> 폴더를 만들고 (예: CA16김연아123456)
    만들어진 폴더를 우클릭하여 나오는 드롭메뉴에서
    폴더 공유설정으로 kyagrd@gmail.com 에게 공유 (편집권한)
  • Google 메일 계정만 있으면 Google Drive 서비스 이용 가능 
  • Google 메일 계정은 무료로 만들 수 있으며
    참고로 안드로이드 스마트폰 사용자는 누구나 이미 보유

MIPS 어셈블리 실습

  • SPIM 시뮬레이터 사용
  • MIPS 어셈블리 syntax coloring 지원하는텍스트 에디터
    • Sublime Text
    • Notepad++
    • Vim
    • Emacs

Jump 연산 복습

  • jal label // 함수 호출에 사용
    1. $ra 에 $pc + 4 저장
    2. label 위치로 $pc 이동
  • jr $ra // 함수 리턴에 주로 사용
    • 레지스터에 저장된 주소로 $pc 이동

MIPS 함수 호출의 기본

  • $ra에 함수 호출자(caller)의 return address가 저장됨

  • 함수 인자는 $a0 ~ $a3에 저장

  • jal 명령으로 함수 호출

  • 함수 내용 실행

  • 함수 결과값 $v0 ~ $v1에 저장

  • jr $ra 로 함수 리턴

(하지만 이것만 갖고는 안된다)

MIPS 함수 호출과 스택

  • leaf function 말단 함수의 경우 꼭 $ra등 저장하지 않아도 됨 

  • non-leaf function인 경우 함수 호출시 잃게 되는 정보 중 함수 호출 후에도 필요한 것들을 스택에 저장

    • $ra 는 반드시 저장, $s0 ~ $s7 중 사용하는 것을 저장,
      그 외 다른 레지스터나 다른 값도 필요에 따라 저장

    • 호출받은 함수(callee)입장에서 함수 진입과 동시에 수행

    • 스택 저장 예시 ($ra 하나만 저장할 때)

      addi $sp, $sp, -4
      sw $ra 0($sp)
      # 다른 함수 호출 등 함수 내용 실행
      lw $ra 0($sp)
      addi $sp, $sp, 4
      jr $ra

MIPS 함수 호출 추가

  • 프레임 포인터 레지스터 $fp는 이전 $sp의 위치 (즉 함수에 진입 직후 스택에 로칼 정보 저장 전 포인터 위치) 기억용
    • 보통은 사용할 필요 없음 (함수 실행 중 동적으로 $sp를 변화시키는 특이한 경우 처음 $sp 위치가 상수값으로 계산이 어려워 저장하고 있을 필요가 있을 때만 사용)
    • 하지만 사용한다면 함수 호출 이후에도 보존되어야 함
  • $gp 도 함수 호출 전후로 보존되어야 함
    • 근데 이것도 웬만해선 변화시킬 일이 없다
    • x 가 data 영역의 label일 때 다음 둘 실행 후 $t0 값 동일
      • lw $t0, x($gp)
      • la $t1, x
        lw $t0, 0($t0)

함수 호출 (C 프로그램)

int add(int x, int y) { // leaf function
    return x + y;       // 말단 함수
}

int twice(int x) {    // non-leaf function
    return add(x, x); // 다른 함수를 부르는 함수
}

int main(void) {
    int n = twice(8);
    printf("%d", n);
    return 0;
}

함수 호출 (MIPS 어셈블리)

int add(int x, int y) {
    return x + y;
}

int twice(int x) {
    return add(x, x);
}

int main(void) {
    int n = twice(8);
    printf("%d", n);
    return 0;
}

<잘못된 버전>

add:
    add $v0,$a0,$a1
    jr $ra

twice:
    move $a1, $a0
    jal add
    jr $ra

main:
    li $a0, 8
    jal twice
    # 출력 시스템 콜
    jr $ra

함수 호출 

int add(int x, int y) {
    return x + y;
}

int twice(int x) {
    return add(x, x);
}

int main(void) {
    int n = twice(8);
    printf("%d", n);
    return 0;
}
add:
    add $v0,$a0,$a1
    jr $ra

twice:
    addi $sp, $sp, -4
    sw $ra, 0($sp)
    move $a1, $a0
    jal add
    lw $ra, 0($sp)
    addi $sp, $sp, 4
    jr $ra

main:
    addi $sp, $sp, -4
    sw $ra, 0($sp)
    li $a0, 8
    jal twice
    # 출력 시스템 콜
    lw $ra, 0($sp)
    addi $sp, $sp, 4
    jr $ra

컴퓨터아키텍처

By 안기영 (Ahn, Ki Yung)

컴퓨터아키텍처

2016-03-30

  • 2,773