Procedures - Calling Conventions

김민욱·2025년 4월 23일

Passing control flow

stack을 사용하여 procedure의 call과 return을 지원.

procedure call

call label
  1. stack에 return address를 push한다.
    * return address: call 이후 수행할 명령어 위치
  2. label로 점프한다.

procedure return

ret
  1. stack에서 return address를 pop한다.
  2. return address로 점프한다.

Example with code

0000000000400540 <mulstore> :
	.
	.
	400544: callq 400550 <mul2>
	400549: mov %rax, (%rbx)
	.
	.
0000000000400550 <mul2> :
	400550: mov %rdi, %rax
    .
	.
    400557: retq

400544: callq 400550 <mul2>:
%rip에는 400544가 저장되어있다.
1. stack에 400549를 push한다.
2. 400550으로 점프한다.

400557: retq:
1. stack pop을 수행하여 400549를 꺼낸다.
2. 400549로 점프한다.

400549: mov %rax, (%rbx):
의미 - %rbx 안에 든 주소에 %rax를 저장하겠다.
수행- %rsp가 8만큼 줄어들고 생긴 공간에 %rax 값을 저장한다.

Passing data flow

procedure의 argument는 아래와 같은 순서대로 레지스터에 저장된다.
Argument : %rdi, %rsi, %rdx, %rcx, %r8, %r9
Return value : %rax

Argument가 6개를 초과할 경우 stack에 저장한다.
사용되는 stack 주소는 다음과 같다.
Argument build area : 8(%rsp), 16(%rsp), ... , 8n(%rsp)

Example with code

// C mulstore
void mulstore(long x, long y, long *dest)
{
	long t = mul2(x, y);
    *dest = t;
}
// C mul2
long mul2(long a, long b)
{
	long s = a * b;
    return s;
}
// Assembly mulstore
0000000000400540 <mulstore> :
	// x -> %rdi, y -> %rsi, dest -> %rdx
	.
	.
    400541: mov %rdx, %rbx // %rbx에 dest 저장
	400544: callq 400550 <mul2> // mul2(x, y)
    // t는 %rax
	400549: mov %rax, (%rbx) // dest주소에 t값 저장
	.
	.
// Assembly mul2
0000000000400550 <mul2> :
	// a -> %rdi, b -> %rsi
	400550: mov %rdi, %rax // %rax에 a 저장
    400553: imul %rsi, %rax // %rax = %rax*%rsi
	// s -> %rax
    400557: retq

<참고자료>
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition
안성용, "시스템소프트웨어", 부산대학교

0개의 댓글