본문 바로가기
보관/시스템 소프트웨어

Procedure Call in MIPS(1)

by unhyepnhj 2024. 10. 16.

MIPS의 함수 호출

  • PC(Program Counter): 실행할 CPU instruction의 주소를 가지고 있는 레지스터
  • $gp: global pointer
  • $sp: stack pointer

MIPS의 논리 주소 영역은 Code, Data, Stack(+Heap) 영역으로 구성된다.

논리 주소:
ISA에 의해 그 메모리 범위가 결정되는, 물리적 메모리와는 관계 없이 각 프로그램 실행 시 생성되는 상대적 주소
ex: MIPS ISA의 주소 체계는 32bit를 가지므로, 총 4GB의 메모리 주소 할당 

 

Code 영역: 기계어를 컴파일한 instruction 저장

Code 영역에는 작성한 프로그램을 컴파일해 만들어진 기계어들이 저장된다. Code 영역 내에서 PC(Program Counter)가 가리키는 코드가 실행되며, 함수 호출 등이 발생하면 PC는 해당 부분으로 jump한다.

 

※ Code 영역은 기계어로 구성되며, 이들 기계어는 Read-only이므로 Code 영역의 값 또한 Read-only로 변경할 수 없다. Code 영역에는 무엇을 무엇으로 바꾸는지에 대한 instruction만이 포함되며, 프로그램이 진행됨에 따라 수정이 필요한 변수 등의 값들은 Data 영역과 Stack 영역에 나누어져 들어가게 된다.

 

Data 영역: 프로그램 전체에서 사용되는 정보 저장

전역 변수나 정적 변수 등과 같이, 프로그램의 시작부터 종료까지 유지되어야 하는 값들이 Data 영역에 저장된다. 

 

Stack 영역: 함수 호출 및 return과 관련한 정보 저장
함수와 운명을 같이 하는 지역 변수 등의 값들은 Stack 영역에 저장된다. 함수 호출 이후 PC가 돌아올 위치, 함수 호출 시 전달해야 하는 parameter나 호출된 함수의 지역 변수 등, 함수 호출 및 return과 관련된 정보들 또한 Stack 영역에 저장된다.

malloc: 포인터가 가리키는 공간을 동적으로 생성

malloc을 사용해 동적으로 생성된 공간을 가리키는 포인터 자체는 지역 변수이므로 포인터를 포함한 지역 변수는 함수 return 시 소멸되지만, 포인터가 가리키는 공간은 동적인 데이터에 해당해 함수 return 이후에도 소멸되지 않아 작성자가 free()해 주어야 한다.

이러한 동적 공간은 함수와 운명을 같이 하는 값이 아니기에 Stack 영역의 위에서(pop되는 top에서)부터가 아니라, Stack과 반대 방향에서부터 공간을 할당하는 별도의 힙(Heap) 영역에 저장된다.

 

+ MIPS Resgister Naming

number name usage
$0 zero constant 0
$1 at 어셈블러가 사용
$2, $3 v0, v1 수식 계산 및 함수 결과값 저장
$4 ~ $7 a0 ~ a3 arguments
$8 ~ $15 t0 ~ t7 temporary
$16 ~ $23 s0 ~ s7 saved(preserved across a call)
$24, $25 t8, t9 temporary
$26, $27 k0, k1 OS가 사용함
$28 gp pointer for global area
$29 sp stack pointer
$30 fp frame pointer
$31 ra return address
  • $4~7: agrument가 4개 이하일 때 해당 레지스터를 이용하여 전달, 5개 이상일 때는 Stack을 이용하여 전달한다.
  • $28(gp): Data 영역을 가리키는 용도로 사용
  • $29(sp), $30(fp): 스택을 가리키는 용도로 사용
  • $31(ra): 함수 호출 후 되돌아가야 하는(PC의 값을 ra 레지스터에 저장된 값으로 변경) 위치가 기본적으로 저장된다. 함수가 여러 번(중첩해서) 호출될 때 하나뿐인 ra 레지스터에 각 caller의 return address를 모두 저장할 수 없으므로, 이때 Stack 영역에 함수의 return address를 추가적으로 저장한다.
$8~15, $16~23, $26, $27: 변수를 레지스터에 mapping할 때 사용

변수들(지역, 전역 both)을 Stack(또는 Data)에 저장해 사용하지만, Stack은 속도가 빠르지 않으므로 가능하면 변수들을 레지스터에 mapping하여 사용한다. 

함수가 호출될 때, 해당 함수를 호출한 원래 함수(caller)는 자신이 사용하며 레지스터에 저장해놓은 값들이 새로 호출된 함수(callee)가 해당 레지스터를 사용함에 따라 변경될 것을 예상하여 함수 호출 전에 해당 레지스터의 값들을 스택에 save해 놓아야 한다(백업 개념). 이처럼 레지스터 값을 save할 책임이 원래 함수(caller)에게 있는 레지스터가 temporary 레지스터 (t0~t9, $8~15, 24, 25)이다.

이와 반대로 saved 레지스터(s0~s7, $16~23)는 caller가 별도의 save 없이 함수를 호출하더라도 기존 값들이 보존될 것을 보장하는 레지스터이므로, save의 책임이 호출된 함수(callee)에게 있다(callee가 saved 레지스터를 사용하고 싶을 경우 해당 레지스터에 저장되어 있던 기존 데이터(caller의 데이터)를 save하고 return 전에 복원해야 함).

'보관 > 시스템 소프트웨어' 카테고리의 다른 글

System Software and Program Execution(1)  (0) 2024.10.17
Procedure Call in MIPS(3)  (0) 2024.10.16
Procedure Call in MIPS(2)  (0) 2024.10.16
MIPS + MIPS Operations  (0) 2024.10.13
Introduction to System Software  (0) 2024.10.10