컴퓨터아키텍처
Computer Architecture
2016-03-30
MIPS 함수 호출과 스택 사용
과제 제출 안내
- Google Drive 공유 폴더를 통해 (종이 X, 메일 X)
-
[새로 만들기] 버튼을 눌러
CA16<이름><학번> 폴더를 만들고 (예: CA16김연아123456)
만들어진 폴더를 우클릭하여 나오는 드롭메뉴에서
폴더 공유설정으로 kyagrd@gmail.com 에게 공유 (편집권한) - Google 메일 계정만 있으면 Google Drive 서비스 이용 가능
- Google 메일 계정은 무료로 만들 수 있으며
참고로 안드로이드 스마트폰 사용자는 누구나 이미 보유
MIPS 어셈블리 실습
- SPIM 시뮬레이터 사용
- 홈페이지에서 다운로드
http://spimsimulator.sourceforge.net/
- 홈페이지에서 다운로드
- MIPS 어셈블리 syntax coloring 지원하는텍스트 에디터
- Sublime Text
- Notepad++
- Vim
- Emacs
Jump 연산 복습
-
jal label // 함수 호출에 사용
- $ra 에 $pc + 4 저장
- 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,845