Setup the argument for user program in process_exec()
<aside>
<img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/99abd4a7-3021-4fa1-9e83-eef264b263a4/angry_mjh.png" alt="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/99abd4a7-3021-4fa1-9e83-eef264b263a4/angry_mjh.png" width="40px" /> process_exec()
함수에 있는 “유저 프로그램”을 위한 인자를 세팅해봅시다.
</aside>
This section summarizes important points of the convention used for normal function calls on 64-bit x86-64 implementations of Unix. Some details are omitted for brevity. For more detail, you can refer System V AMD64 ABI.
<aside> <img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/99abd4a7-3021-4fa1-9e83-eef264b263a4/angry_mjh.png" alt="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/99abd4a7-3021-4fa1-9e83-eef264b263a4/angry_mjh.png" width="40px" /> 이번 절에서는, 유닉스의 64비트 x86-64 구현들에 있는- 일반적인 함수호출 규약의 중요한 포인트들을 요약해보도록 하겠습니다.
몇몇 디테일은 간결성을 위해 생략되었습니다. 디테일한 정보를 원한다면, System V AMD64 ABI를 참고하세요.
</aside>
The calling convention works like this:
- User-level applications use as integer registers for passing the sequence
%rdi
,%rsi
,%rdx
,%rcx
,%r8
and%r9
.- The caller pushes the address of its next instruction (the return address) on the stack and jumps to the first instruction of the callee. A single x86-64 instruction,
CALL
, does both.- The callee executes.
- If the callee has a return value, it stores it into register RAX.
- The callee returns by popping the return address from the stack and jumping to the location it specifies, using the x86-64
RET
instruction.
<aside> <img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/99abd4a7-3021-4fa1-9e83-eef264b263a4/angry_mjh.png" alt="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/99abd4a7-3021-4fa1-9e83-eef264b263a4/angry_mjh.png" width="40px" /> 호출 규약은 다음과 같습니다 :
%rdi
, %rsi
, %rdx
, %rcx
, %r8
, %r9
시퀀스들을 전달하기 위해 정수 레지스터를 사용합니다.CALL
이라는 x86-64 인스트럭션 하나가 이 두 가지를 모두 수행합니다.RET
*(리턴)*를 사용해서, 스택에 받았던 리턴 어드레스를 pop하고 그 주소가 가리키는 곳으로 점프함으로써 리턴됩니다.
</aside>Consider a function
f()
that takes three int arguments. This diagram shows a sample stack frame and register state as seen by the callee at the beginning of step 3 above, supposing thatf()
is invoked asf(1, 2, 3)
. The initial stack address is arbitrary:
<aside>
<img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/99abd4a7-3021-4fa1-9e83-eef264b263a4/angry_mjh.png" alt="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/99abd4a7-3021-4fa1-9e83-eef264b263a4/angry_mjh.png" width="40px" /> 세 개의 정수 인자를 받는 함수 f()
가 있다고 생각해봅시다.
아래 도식은 위의 3번 항목에 있는 피호출자가 실행되는 시점에, 스택 프레임과 레지스터 상태가 어떤 식으로 되어있는지에 대한 예시를 보여줍니다. f()
가 f(1, 2, 3)
으로 호출되었다고 가정합시다.
초기화된 스택의 주소는 임의의 숫자로 치면 다음과 같습니다 :
</aside>
+----------------+
stack pointer --> 0x4747fe70 | return address |
+----------------+
RDI: 0x0000000000000001 | RSI: 0x0000000000000002 | RDX: 0x0000000000000003
The Pintos C library for user programs designates
_start()
, inlib/user/entry.c
, as the entry point for user programs. This function is a wrapper aroundmain()
that callsexit()
ifmain()
returns:
<aside>
<img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/99abd4a7-3021-4fa1-9e83-eef264b263a4/angry_mjh.png" alt="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/99abd4a7-3021-4fa1-9e83-eef264b263a4/angry_mjh.png" width="40px" /> 유저 프로그램을 위한 Pintos C 라이브러리는 _start()
함수를 유저 프로그램의 시작 포인트로 지정합니다. _start()
는 lib/user/entry.c
에 있습니다.
여기서 _start()
는 main()
함수를 감싸고 있는 함수입니다. main()
은 리턴되면서 exit()
을 호출하게 됩니다.
</aside>