from __do_fork ()
/* Use iretq to launch the thread *** 실제로 context switching을 하는 함수 *** */
void
do_iret (struct intr_frame *tf) {
/* Structure -> CPU Register로 데이터 이동 (Load) */
__asm __volatile ( // 입력한 그대로 사용
"movq %0, %%rsp\n" // 인자 *tf의 주소를 Register Stack Pointer RSP에 저장
"movq 0(%%rsp),%%r15\n" // rsp위치의 값(stack 시작)을 레지스터 r15에 저장
"movq 8(%%rsp),%%r14\n" // rsp+8위치의 값을 레지스터 r14에 저장
"movq 16(%%rsp),%%r13\n" // rsp+16위치의 값을 레지스터 r16에 저장
"movq 24(%%rsp),%%r12\n" // rsp+24 위치의 값을 레지스터 r12에 저장
"movq 32(%%rsp),%%r11\n"
"movq 40(%%rsp),%%r10\n"
"movq 48(%%rsp),%%r9\n"
"movq 56(%%rsp),%%r8\n"
"movq 64(%%rsp),%%rsi\n"
"movq 72(%%rsp),%%rdi\n"
"movq 80(%%rsp),%%rbp\n"
"movq 88(%%rsp),%%rdx\n"
"movq 96(%%rsp),%%rcx\n" // rsp+96 위치의 값을 레지스터 rcx에 저장
"movq 104(%%rsp),%%rbx\n" // rsp+104 위치의 값을 레지스터 rbx에 저장
"movq 112(%%rsp),%%rax\n" // rsp+112 위치의 값을 레지스터 rax에 저장
"addq $120,%%rsp\n" // rsp 위치를 정수 레지스터 다음으로 이동-> rsp->es
"movw 8(%%rsp),%%ds\n" // rsp+8위치의 값을 레지스터 ds(data segment)에 저장
"movw (%%rsp),%%es\n" // rsp 위치의 값을 레지스터 es(extra segment)에 저장
"addq $32, %%rsp\n" // rsp 위치를 rsp+32로 이동. rsp->rip
"iretq" // rip 이하(cs, eflags, rsp, ss) 인터럽트 프레임에서 CPU로 복원. (직접 ACCESS 불가능)
: // 인터럽트 프레임의 rip 값을 복원함으로서 기존에 수행하던 스레드의 다음 명령 실행 ... ?
: "g"((uint64_t)tf) // g=인자. 0번 인자로 tf를 받음
: "memory");
}
do_iret 함수 해석이 함수는 iretq 명령어를 사용하여 저장된 인터럽트 프레임 (intr_frame)의 상태를 CPU 레지스터에 복원하고, 중단된 스레드(또는 프로세스)의 실행을 재개합니다. 주로 문맥 교환(context switching) 시에 사용됩니다.
struct intr_frame *tf에 저장된 상태 정보를 CPU 레지스터에 복원하여, 스레드의 실행을 이어갑니다.iretq 명령어를 사용하여 인터럽트 이전 상태로 복귀합니다.movq %0, %%rsprsp (Stack Pointer)를 tf로 설정합니다.%0: 입력으로 받은 tf의 주소를 사용.%%rsp: CPU의 스택 포인터 레지스터.movq ...)rsp가 가리키는 메모리 주소에서 정수 레지스터 값을 읽어 CPU 레지스터에 복원합니다.r15, r14, ..., rax: 정수 레지스터 복원.intr_frame 구조체의 정수 레지스터 배열과 일치합니다.addq $120, %%rsp)rsp)를 데이터 세그먼트(ds)와 추가 세그먼트(es) 영역으로 이동.es, ds)를 복원할 준비를 합니다.movw ...)ds와 es를 복원.ds (Data Segment): 데이터가 저장되는 메모리 세그먼트.es (Extra Segment): 추가 데이터 영역.addq $32, %%rsp)rip(Instruction Pointer) 이하로 이동.rip, cs, eflags, rsp, ss를 복원하기 위한 준비.iretq 명령어iretq는 CPU의 인터럽트 프레임에 저장된 정보를 사용하여 다음 실행 상태를 복원합니다.rip (Instruction Pointer): 실행할 명령의 주소.cs (Code Segment): 명령어의 세그먼트.eflags (Flags Register): CPU 상태 플래그.rsp (Stack Pointer): 스택의 현재 위치.ss (Stack Segment): 스택 세그먼트.struct intr_frame *tfr15~rax, ds, es)와 플래그(eflags) 값을 스택에서 읽어 복원.rsp)는 intr_frame의 메모리 구조에 따라 조정됩니다.iretq 명령어의 핵심 역할iretq를 통해 rip, cs, eflags, rsp, ss를 복원.rip 값을 사용해 인터럽트가 발생하기 전 실행 중이던 명령을 재개.do_iret는 저장된 인터럽트 프레임(intr_frame)의 상태를 복원하여 중단된 스레드 또는 프로세스의 실행을 재개하는 역할을 합니다. 어셈블리 코드로 구현되어 있으며, 문맥 교환에서 중요한 함수입니다. CPU 레지스터와 스택을 직접 다루므로 매우 저수준에서 실행됩니다.