ν•¨μˆ˜ 호좜이 ν˜ΈμΆœλ˜λŠ” κ³Όμ • μ‚΄νŽ΄λ³΄κΈ°. SP, BP, LP(IP) λ ˆμ§€μŠ€ν„°λ“€μ˜ 값이 μ–΄λ–»κ²Œ λ³€κ²½λ˜κ³ , λ³΅κ΅¬λ˜λŠ”μ§€ κ·Έ 원리에 λŒ€ν•΄.

11 minute read

3λ…„κ°„ μ‚°μ—…κΈ°λŠ₯μš”μ›μœΌλ‘œ 볡무 ν•˜κ³ , 볡학해 컴곡과 μˆ˜μ—…μ„ λ“£κ³  μžˆμŠ΅λ‹ˆλ‹€. κ·Έλ™μ•ˆ 많이 λ°°μ› λ‹€κ³  μƒκ°ν–ˆλŠ”λ°, μ—¬μ „νžˆ λΆ€μ‘±ν•œ 뢀뢄이 λ§Žλ„€μš” ^^;; μ—­μ‹œ 세상도 λ„“κ³  κ³΅λΆ€μ˜ 길도 넓은 것 κ°™μŠ΅λ‹ˆλ‹€.

λ“€μ–΄κ°€λ©°

λΆ„λͺ… β€œλ§ˆμ΄ν¬λ‘œ ν”„λ‘œμ„Έμ„œβ€ μˆ˜μ—… λ•Œ μ–΄μ…ˆλΈ”λ¦¬λ₯Ό ν•˜λ©΄μ„œ λ°°μ› λ˜ 것 같은데, ꡰ볡무λ₯Ό ν•˜κ³  μ˜€λ‹ˆκΉŒ λ‹€ κΉŒλ¨Ήμ—ˆλ‹€ γ…‹γ…‹ 운영체제 μˆ˜μ—…μ„ λ“€μœΌλ©΄μ„œ 이 뢀뢄을 λ‹€μ‹œ 보게 될 일이 μƒκ²ΌλŠ”λ°, 잘 μ„€λͺ…ν•œ μžλ£Œλ„ μžˆμ§€λ§Œ λ‚΄ μž…λ§›μ— 맞게 이리저리 μ‘°μ •ν•΄ κΈ€λ‘œ 정리해본닀 γ…Žγ…Ž

μ•„, 미리 λ§ν•΄λ‘μ§€λ§Œ C언어와 x86-gcc 컴파일러λ₯Ό κΈ°μ€€μœΌλ‘œ μ„€λͺ…ν•œλ‹€. 그리고 μ—¬κΈ°μ„œ μ„€λͺ…ν•˜λŠ” push, pop 같은 λͺ…λ Ήμ–΄λŠ” assembly λͺ…λ Ήμ–΄λ₯Ό μ˜λ―Έν•˜λ©°, x86-gccμ—μ„œ μ‚¬μš©ν•˜λŠ” CISC λͺ…령어셋을 λ”°λ₯Έλ‹€. μ–΄μ…ˆλΈ”λ¦¬ 문법은 β€œIntel 문법”을 λ”°λžμŒλ„ λ°νžŒλ‹€.

Stackframeμ΄λž€??

일단 Stackframe μžμ²΄λŠ” μŠ€νƒ λ©”λͺ¨λ¦¬μ— μ‘΄μž¬ν•˜λŠ” 곡간 쀑 일뢀이닀. ν•¨μˆ˜μ½œμ΄ λ°œμƒν•  λ•Œ, κ·Έ ν•¨μˆ˜μ˜ life cycle λ™μ•ˆ μ‚¬μš©ν•˜λŠ” μŠ€νƒ λ©”λͺ¨λ¦¬ 곡간인데, 여기에 ν•¨μˆ˜μ˜ 인자(args)와 각쒅 μ§€μ—­λ³€μˆ˜μ™€ 쀑간 μ—°μ‚° 결과듀이 μ €μž₯λœλ‹€.

μŠ€νƒ λ©”λͺ¨λ¦¬μ—μ„œ ν•¨μˆ˜μ½œκ³Ό κ΄€λ ¨λœ 뢀뢄이기 λ•Œλ¬Έμ— β€œcall stack”라고 λΆ€λ₯΄κΈ°λ„ ν•œλ‹€.

Registers

μŠ€νƒ ν”„λ ˆμž„μ΄ λ™μž‘ν•˜λŠ” κ³Όμ •μ—μ„œ μ‚¬μš©ν•˜λŠ” λ ˆμ§€μŠ€ν„°λ“€λΆ€ν„° μ‚΄νŽ΄λ³΄μž. 일단 μ΄λ¦„λ§Œ κ°„λ‹¨νžˆ μ‚΄νŽ΄λ³Έλ‹€.

Overview

Stack Frame의 이해λ₯Ό 돕기 μœ„ν•΄ β€œμ•„μ£Ό λ§Žμ΄β€ μΆ”μƒν™”λœ λ²„μ „μž…λ‹ˆλ‹€.

  • Stack Pointer; SP
    • μŠ€νƒμ˜ κ°€μž₯ μ•„λž˜(lowest)의 μ£Όμ†Œκ°’μ„ κ°€λ¦¬ν‚€λŠ” λ ˆμ§€μŠ€ν„°μ΄λ‹€.
    • λŒ€μΆ© current, latest μœ„μΉ˜λ₯Ό κ°€λ¦¬ν‚€λŠ” λ ˆμ§€μŠ€ν„°μ΄λ‹€.
    • push λͺ…λ Ήμ–΄λ₯Ό μˆ˜ν–‰ν•˜λ©΄, SP 값이 κ°μ†Œν•œλ‹€. (μŠ€νƒμ€ μœ„μ—μ„œ μ•„λž˜λ‘œ μžλΌλ‹ˆκΉŒ!): SP - 4
    • pop λͺ…λ Ήμ–΄λ₯Ό μˆ˜ν–‰ν•˜λ©΄, SP 값이 μ¦κ°€ν•œλ‹€. SP + 4
    • ν•¨μˆ˜ μ’…λ£Œλ  λ•Œ, μŠ€νƒ λ©”λͺ¨λ¦¬λ₯Ό μ •λ¦¬ν•˜λŠ”λ°λ„ μ‚¬μš©ν•œλ‹€.
      • μš” 뢀뢄은 λ’€μ—μ„œ ν•¨μˆ˜κ°€ μ’…λ£Œλ˜λŠ” 상황을 μ–˜κΈ°ν•  λ•Œ 닀룬닀.
  • Base Pointer; BP
    • μŠ€νƒ ν”„λ ˆμž„μ˜ μ‹œμž‘ μœ„μΉ˜λ₯Ό κ°€λ¦¬ν‚€λŠ” λ ˆμ§€μŠ€ν„°μ΄λ‹€.
    • ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜λŠ” λ™μ•ˆ BPλŠ” κ·Έ ν”„λ ˆμž„μ˜ μ‹œμž‘ μœ„μΉ˜μ— κ³ μ •λ˜μ–΄ κ·Έ 값이 λ³€ν•˜μ§€ μ•ŠλŠ”λ‹€.
    • ν•¨μˆ˜ λ‚΄μ˜ 맀개 λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•  λ•Œ, κΈ°μ€€μ μœΌλ‘œ μ‚¬μš©ν•œλ‹€.
      • μš” 뢀뢄도 λ’€μ—μ„œ λ§€κ°œλ³€μˆ˜μ— λŒ€ν•΄ μ–˜κΈ°ν•  λ•Œ 닀룬닀.
    • ν•¨μˆ˜ λ‚΄μ˜ 지역 λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•  λ•Œ, κΈ°μ€€μ μœΌλ‘œ μ‚¬μš©ν•œλ‹€.
      • μš”κ²ƒλ„ λ’€μ—μ„œ μ§€μ—­λ³€μˆ˜μ— λŒ€ν•΄ μ–˜λΌν•  λ–„ 닀룬닀.
  • Link Pointer; LP λ˜λŠ” Index Pointer; IP
    • ν•¨μˆ˜ 호좜이 μ’…λ£Œλœ ν›„ 볡귀할 μ½”λ“œ μ£Όμ†Œλ₯Ό λ‹΄λŠ” λ ˆμ§€μŠ€ν„°
    • ν•¨μˆ˜ 호좜이 λ°œμƒν•˜λ©΄, κ·Έ μ§€μ μ˜ μ½”λ“œ μ£Όμ†Œλ₯Ό LP에 μ €μž₯ν•œλ‹€.
    • ν•¨μˆ˜κ°€ μ’…λ£Œλ˜λ©΄, LP에 μ €μž₯된 μ½”λ“œ μ£Όμ†Œλ‘œ μ΄λ™ν•œλ‹€. (jmp lp)
    • 처음 보면 ν—·κ°ˆλ¦΄ μˆ˜λ„ μžˆλŠ”λ°, LPκ°€ λ‹΄λŠ” μ£Όμ†Œκ°’μ€ μŠ€νƒ μ˜μ—­μ΄ μ•„λ‹ˆλΌ μ½”λ“œ μ˜μ—­μ΄λ‹€!!

μ‚¬μš©λ˜λŠ” μ‹œλ‚˜λ¦¬μ˜€

ν•¨μˆ˜κ°€ 호좜되고, 리턴 λ˜λŠ” κ³Όμ •μ—μ„œ μœ„μ˜ λ ˆμ§€μŠ€ν„°λ“€μ΄ μ–΄λ–»κ²Œ λ™μž‘ν•˜λŠ”μ§€ μ‚΄νŽ΄λ΄…μ‹œλ‹€. μœ„μ˜ κ·Έλ¦Όκ³Ό ν•¨κ»˜ 과정을 λ”°λΌκ°€λ΄…μ‹œλ‹€. (Intel 문법을 κΈ°μ€€μœΌλ‘œ μž‘μ„± λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.)

  1. ν•¨μˆ˜ 호좜 직전 (caller saves)
    1. 호좜 ν•¨μˆ˜λŠ” ν•¨μˆ˜μ˜ 인자 argsκ°€ μŠ€νƒμ— μ €μž₯함. (push 100)
    2. ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œ μ§€μ μ˜ μ½”λ“œ μ£Όμ†Œλ₯Ό μŠ€νƒμ— μ €μž₯함.
  2. ν•¨μˆ˜ μ‹€ν–‰ 직전
    1. 이전 ν•¨μˆ˜μ˜ BP 값을 μŠ€νƒμ— μ €μž₯함. (push rbp)
    2. 그리고 BP 값을 ν˜„μž¬μ˜ SP κ°’μœΌλ‘œ μ—…λŽƒν•¨. (mov rbp, rsp)
    3. ν•¨μˆ˜μ˜ 둜컬 λ³€μˆ˜λ“€μ„ 확보함. (sub rsp, N)
  3. ν•¨μˆ˜ μ‹€ν–‰ 쀑
    1. BP 값은 ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜λŠ” λ™μ•ˆ μŠ€νƒ ν”„λ ˆμž„μ˜ μ‹œμž‘ μœ„μΉ˜λ₯Ό 가리킀며 고정됨.
    2. SPλŠ” ν˜„μž¬ μŠ€νƒμ˜ μœ„μΉ˜λ₯Ό λ‚˜νƒ€λƒ„. λ³€μˆ˜κ°’μ„ μŠ€νƒμ— μ €μž₯ν•˜κ±°λ‚˜(push), μŠ€νƒμ—μ„œ 빼였면(pop), κ·Έ 값이 μ€„μ–΄λ“€κ±°λ‚˜ λŠ˜μ–΄λ‚¨.
  4. ν•¨μˆ˜ μ’…λ£Œ μ‹œ
    1. SPλ₯Ό μ €μž₯ν•΄λ‘” BP μœ„μΉ˜λ‘œ μ΄λ™μ‹œν‚΄. (mov rsp, rbp)
    2. μŠ€νƒμ— μ €μž₯ν•΄λ’€λ˜ caller ν•¨μˆ˜μ˜ BPλ₯Ό 볡ꡬ함. (pop rbp)
    3. μŠ€νƒμ— μ €μž₯ν•΄λ’€λ˜ 볡귀 μ£Όμ†Œλ₯Ό μ‚¬μš©ν•΄ μ½”λ“œ μ£Όμ†Œλ‘œ 볡귀함.

Access Stack

Allocate stack space for local vars

μœ„μ˜ κ³Όμ • 쀑에 2.3 λ‹¨κ³„μ—μ„œ μΌμ–΄λ‚˜λŠ” ν•¨μˆ˜μ˜ 둜컬 λ³€μˆ˜λ₯Ό ν™•λ³΄ν•˜λŠ” 과정을 쒀더 μ‚΄νŽ΄λ³΄μž.

// example to understand function's local variables
void square(int n) {
  int a;
  double b;
  int arr[100];

  // more complex code
  for (int i=0; i < 10; i++) {
    printf("%d", i);
  }

  return n * n;
}

본인이 Stack Frame을 처음 μ•Œμ•„κ°€λ©΄μ„œ 이해가 μ•ˆ λ˜μ—ˆλ˜ 뢀뢄은 β€œλ‘œμ»¬ λ³€μˆ˜λ₯Ό 확보할 곡간이 μ–Όλ§ˆμΈ 쀄 μ•Œκ³ , sub rsp, Nλ₯Ό ν•˜λŠ” 거지?β€λΌλŠ” μƒκ°μ΄μ—ˆλ‹€. 둜컬 λ³€μˆ˜λŠ” μ½”λ“œλ₯Ό μ§œλŠ” κ³Όμ •μ—μ„œ μ–΄λ–€ κ³³μ—μ„œλ“ μ§€ λ“±μž₯ν•  수 μžˆλ‹€. μœ„μ˜ μ½”λ“œμ²˜λŸΌ ν•¨μˆ˜μ˜ μ²˜μŒμ— μ‚¬μš©ν•˜λŠ” 둜컬 λ³€μˆ˜λ“€μ„ μ •μ˜ν•˜κ³  μ‹œμž‘ν•  μˆ˜λ„ 있고, μ½”λ“œλ₯Ό μ§œλŠ” κ³Όμ •μ—μ„œ (for int i=0; ...)처럼 μžμ—°μŠ€λŸ½κ²Œ μ„ μ–Έλ˜λŠ” κ²½μš°λ„ μžˆλ‹€.

이리저리 μ°Ύμ•„λ³΄λ‹ˆ sub rsp, N λ™μž‘μ—μ„œ μ“°λŠ” N은 컴파일 νƒ€μž…μ— κ²°μ •λœλ‹€κ³  ν•œλ‹€! μ»΄νŒŒμΌλŸ¬κ°€ μ½”λ“œλ₯Ό μ •μ μœΌλ‘œ λΆ„μ„ν•˜μ—¬ ν•¨μˆ˜μ—μ„œ μ“°λŠ” 둜컬 λ³€μˆ˜λ“€μ„ μ „λΆ€ λͺ¨μ€λ‹€. 그리고 그것듀은 각 λ³€μˆ˜ νƒ€μž…μ— λ§žμΆ°μ„œ intλ³€ 4λ°”μ΄νŠΈ, double이면 8λ°”μ΄νŠΈ, int arr[100]이면 400 λ°”μ΄νŠΈβ€¦ 이런 μ‹μœΌλ‘œ 둜컬 λ³€μˆ˜μ˜ 값이 μ €μž₯되기 μœ„ν•œ 값을 κ³„μ‚°ν•΄μ„œ N 값을 κ΅¬ν•œλ‹€κ³  ν•œλ‹€.

Access Args and Local vars

Base PointerλŠ” μž¬λ°ŒλŠ” νŠΉμ„±μ„ 가지고 μžˆλŠ”λ°, BP κΈ°μ€€μœΌλ‘œ μœ„μ—λŠ” N개의 ν•¨μˆ˜ argsκ°€ μœ„μΉ˜ν•˜κ³ , μ•„λž˜λŠ” M개의 둜컬 λ³€μˆ˜κ°€ μŠ€νƒ 곡간 상에 μ‘΄μž¬ν•œλ‹€. κ·Έλž˜μ„œ ν•¨μˆ˜ μ½”λ“œμ—μ„œ ν•¨μˆ˜ argsλ‚˜ 둜컬 λ³€μˆ˜μ— μ ‘κ·Όν•˜λ €λ©΄, BPλ₯Ό κΈ°μ€€μœΌλ‘œ mov eax, [bp + 8]ν•˜κ±°λ‚˜ mov ebx, [bp - 4]ν•΄μ„œ μ ‘κ·Όν•œλ‹€.

그런데 μ—¬κΈ°μ„œ ꢁ금증이 생긴건, β€œμ–΄μ…ˆλΈ”λ¦¬ μ½”λ“œλŠ” 각 둜컬 λ³€μˆ˜κ°€ BP κΈ°μ€€μœΌλ‘œ λͺ‡ offset 만큼 λ–¨μ–΄μ Έ μžˆλŠ”μ§€λ₯Ό μ–΄λ–»κ²Œ μ•Œκ³  [bp - 4]라고 μ°μ–΄μ£ΌλŠ” 거지?β€λΌλŠ” 생각이 λ“€μ—ˆλ‹€.

이것도 이리저리 μ°Ύμ•„λ³΄λ‹ˆ, 정닡은 컴파일 νƒ€μž„μ— μžˆμ—ˆλ‹€ γ…Žγ…Ž μ»΄νŒŒμΌλŸ¬λŠ” 각 지연 λ³€μˆ˜λ“€μ΄ BP κΈ°μ€€ μ–Όλ§ŒνΌ 떨어진 곡간에 μœ„μΉ˜ν•˜λŠ”μ§€ κ·Έ offset 정보λ₯Ό λ‹΄μ•„μ„œ κ΄€λ¦¬ν•œλ‹€. 이λ₯Ό Offset Table λ˜λŠ” Symbol Table라고 ν•œλ‹€.

μ»΄νŒŒμΌλŸ¬λŠ” C μ½”λ“œλ₯Ό μ–΄μ…ˆλΈ”λ¦¬κ³  λ°”κΏ€λ•Œ, 각 둜컬 λ³€μˆ˜λ“€μ„ [bp - ??]둜 μΉ˜ν™˜ν•œλ‹€. ?? 값은 μ•žμ—μ„œ μ–ΈκΈ‰ν•œ Offset Table에 μ˜ν•΄ κ²°μ •λœλ‹€.

ν•¨μˆ˜ μ’…λ£Œμ™€ μ‹œμž‘

ν•¨μˆ˜κ°€ μ’…λ£Œλ  λ•Œμ˜ λ™μž‘

일단 SPλ₯Ό μ›λž˜ μœ„μΉ˜λ‘œ 볡원해야 ν•œλ‹€. 이것은 μ•„λž˜ μ–΄μ…ˆλΈ”λ¦¬ λͺ…λ Ήμ–΄λ‘œ μˆ˜ν–‰ν•  수 μžˆλ‹€.

mov sp, bp    ; BP 값을 SP둜 볡사해 μŠ€νƒμ„ 정리

이제 BP 값을 caller의 BP κ°’μœΌλ‘œ λ³΅μ›ν•œλ‹€. 이것도 μ•„λž˜μ˜ λͺ…λ Ήμ–΄λ‘œ μˆ˜ν–‰ν•  수 μžˆλ‹€.

pop bp

μœ„μ˜ 과정을 톡해 BPκ°€ κ°€λ¦¬ν‚€λ˜ 곳에 μ €μž₯λ˜μ–΄ 있던 caller BP 값이 BP λ ˆμ§€μŠ€ν„°μ— μ €μž₯λœλ‹€. pop이 ν˜ΈμΆœλ˜μ—ˆκΈ° λ•Œλ¬Έμ—, SPλŠ” μžλ™μœΌλ‘œ SP += 4 처리 λœλ‹€ γ…Žγ…Ž μ–΄μ…ˆλΈ”λ¦¬μ—μ„œλŠ” μš” mov와 pop 과정을 ν•©μ³μ„œ leaveλΌλŠ” λͺ…λ Ήμ–΄λ‘œ μ œκ³΅ν•˜κΈ°λ„ ν•œλ‹€.


이제 μŠ€νƒμ— μ €μž₯ν–ˆλ˜ return_addrλ₯Ό LP λ ˆμ§€μŠ€ν„°μ— λ„£μ–΄μ„œ ν•¨μˆ˜ 호좜이 μ’…λ£Œλ  λ•Œ, caller의 μ½”λ“œ μ£Όμ†Œλ‘œ 이동해야 ν•œλ‹€. 이것은 ret λͺ…λ Ήμ–΄λ‘œ μˆ˜ν–‰ν•  수 μžˆλ‹€!

ret λͺ…λ Ήμ–΄λ₯Ό 쒀더 ν’€μ–΄ μ“°λ©΄, μ•„λž˜μ™€ 같을 것이닀.

pop lp
jmp lp

즉, pop ν•˜κ³  jmp ν•˜λŠ” 과정을 λ¬Άμ–΄μ€€κ²Œ ret인 μ…ˆ!!


이후에 Caller μͺ½μ—μ„œ ν• λ‹Ήν–ˆλ˜ argsλ₯Ό pop ν•΄μ£ΌλŠ” 과정도 ν•„μš”ν•œλ°, μ•„λž˜μ˜ ν•¨μˆ˜ 호좜 ν•  λ•Œμ˜ λ™μž‘κ³Ό 같이 μ‚΄νŽ΄λ³΄μž γ…Žγ…Ž

ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œμ˜ λ™μž‘

ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ Stack Frame μ„ΈνŒ…μ„ μœ„ν•΄ 일련의 μ–΄μ…ˆλΈ”λ¦¬ λͺ…령어듀이 ν˜ΈμΆœλ˜λŠ”λ°, Callerκ°€ μˆ˜ν–‰ν•˜λŠ” λΆ€λΆ„κ³Ό Calleeκ°€ μˆ˜ν–‰ν•˜λŠ” λΆ€λΆ„μœΌλ‘œ λ‚˜λ‰œλ‹€.

; Caller Part
push 100
call square(int)

; Callee Part
push bp
mov bp, sp
sub sp, N
  1. ν•¨μˆ˜κ°€ 호좜 되기 전에 Callerμ—μ„œ ν•¨μˆ˜μ— μ „λ‹¬λ˜λŠ” argsλ₯Ό μŠ€νƒμ— push ν•œλ‹€.
  2. call둜 ν•¨μˆ˜ μ½”λ“œλ‘œ μ΄λ™ν•œλ‹€.
    1. μ΄λ•Œ, call λͺ…λ Ήμ–΄μ˜ μ½”λ“œ μ£Όμ†Œλ₯Ό stack frame에 μ €μž₯ν•˜λŠ” push lp 과정도 ν•¨κ»˜ μˆ˜ν–‰λœλ‹€.
    2. 즉, call λͺ…λ Ήμ–΄κ°€ push lp; jmp square인 μ…ˆ.
  3. μ—¬κΈ°μ„œλΆ€ν„° Callee의 μ–΄μ…ˆλΈ”λ¦¬ λΈ”λ‘μ—μ„œ μ‹€ν–‰λ˜λŠ” νŒŒνŠΈλ‹€.
  4. push bp둜 이전 stack frame의 BPλ₯Ό μŠ€νƒμ— μ €μž₯ν•œλ‹€.
  5. mov bp, sp둜 BP의 값을 ν˜„μž¬ stack frame을 μœ„ν•œ κ²ƒμœΌλ‘œ κ΅μ²΄ν•œλ‹€.
  6. sub sp, N으둜 지역 λ³€μˆ˜λ₯Ό ν• λ‹Ήν•œλ‹€.


ν•¨μˆ˜ Termination νŒŒνŠΈκΉŒμ§€ ν•΄μ„œ 같이 보면 μ•„λž˜μ™€ κ°™λ‹€.

; Caller Initialize Part
push 100
call square(int)

; Callee Initialize Part
push bp
mov bp, sp
sub sp, N

; Callee do something...
...

; Callee Termination
leave
ret

; Caller Termination (remove args)
pop

ret을 μ‹€ν–‰ν•΄μ„œ CallerλŠ” ν•¨μˆ˜ ν˜ΈμΆœμ—μ„œ λŒμ•„μ˜¨ ν›„μ—λŠ”, pop으둜 μŠ€νƒμ— λ„£μ–΄λ’€λ˜ ν•¨μˆ˜ argsλ₯Ό λΉΌμ£ΌλŠ” 과정이 μΌμ–΄λ‚œλ‹€!

ν•¨μˆ˜ 리턴값은 eax λ ˆμ§€μŠ€ν„°μ— μ €μž₯λœλ‹€.

λ§Œμ•½ ν•¨μˆ˜μ— 리턴값이 μ‘΄μž¬ν•œλ‹€λ©΄, κ·Έ 값은 eax λ ˆμ§€μŠ€ν„°μ— μ €μž₯λœλ‹€.

; Callee Termination
mov eax, 42
leave
ret

; Caller Termination (remove args)
pop

ν•¨μˆ˜κ°€ ret으둜 μ’…λ£Œλ˜κΈ° 전에 mov eax, xxxλ₯Ό 톡해 eax λ ˆμ§€μŠ€ν„°μ— λ‹΄κΈ΄λ‹€. 그러면 콜러 ν•¨μˆ˜λŠ” eax에 μ €μž₯된 리턴 값을 μ‚¬μš©ν•˜κ±°λ‚˜, 콜러 ν•¨μˆ˜μ˜ μŠ€νƒμ— μ–΄λ–€ λ³€μˆ˜λ‘œ μ €μž₯ν•œλ‹€.

리턴 값은 λ‹€λ₯Έ λ ˆμ§€μŠ€ν„°κ°€ μ•„λ‹ˆλΌ 항상 eax에 μ €μž₯λ˜λŠ”λ°, 이것은 x86 μ•„ν‚€ν…μ²˜μ—μ„œ β€œCalling Convention”이기 λ•Œλ¬Έμ΄λ‹€. ν•΄λ‹Ή κ·œμ•½μ—μ„œλŠ” ν•¨μˆ˜ 리턴 값은 eax λ ˆμ§€μŠ€ν„°μ— 담도둝 μ •μ˜ν•˜κ³  μžˆλ‹€. 사싀 eax λ ˆμ§€μŠ€ν„°λŠ” β€œλˆ„μ‚°κΈ°(Accumulator) λ ˆμ§€μŠ€ν„°β€λΌλŠ” μ΄λ¦„μœΌλ‘œ, μ‚°μˆ  μ—°μ‚°μ˜ κ²°κ³Όλ₯Ό λ‹΄κΈ° μœ„ν•΄ λ””μžμΈλœ λ ˆμ§€μŠ€ν„°μ΄μ§€λ§Œ, μš” ν•¨μˆ˜ 리턴 값을 μ €μž₯ν•˜λŠ” μš©λ„λ‘œλ„ μ‚¬μš©λ˜λŠ” 것이닀.

Overall ASM Code

square(int):
  push bp
  mov bp, sp
  ; Do multiplication
  leave
  ret

main:
  push bp
  mov bp, sp
  push 100
  call square(int)
  pop

References