
argument_stack 함수는 PintOS에서 프로세스의 인자(argument)들을 스택에 저장하는 역할을 합니다. 이 함수는 프로그램이 실행될 때 필요한 인자들을 스택에 적절하게 배치하여 프로그램이 이를 참조할 수 있도록 합니다.
함수의 동작을 간단히 설명하면 다음과 같습니다
인자로 전달된 argv는 프로세스의 인자들을 저장한 문자열 배열이고, argc는 인자의 개수입니다.
함수는 먼저 문자열 인자들을 스택에 저장합니다. 역순으로 인자를 처리하면서 각 문자를 스택에 하나씩 저장합니다. 이때 스택 포인터(rsp)를 조정하여 스택에 문자를 저장하고 해당 문자의 주소를 arg_address 배열에 저장합니다.
다음으로 워드 정렬(word-align) 패딩을 수행합니다. 스택 포인터를 조정하여 스택의 주소가 8의 배수가 되도록 맞춥니다. 필요한 패딩 바이트를 0으로 채웁니다.
인자들의 주소를 스택에 저장합니다. arg_address 배열을 역순으로 순회하면서 각 주소를 스택에 저장합니다. 이때, 마지막으로 NULL 주소를 스택에 저장합니다.
마지막으로 함수 호출 규약에 따라 RDI와 RSI 레지스터를 설정합니다. RDI는 인자의 개수(argc)를, RSI는 스택의 주소를 가리킵니다.
위의 과정을 통해 argument_stack 함수는 프로그램의 인자들을 스택에 적절하게 저장하여 프로그램이 실행될 때 인자들에 접근할 수 있도록 합니다.
argument_stack 코드입니다
void argument_stack(char **argv, int argc, struct intr_frame *if_) {
char *arg_address[128]; // 인자 주소를 저장할 배열
// Part A: Word-align (단어 정렬)
for (int i = argc - 1; i >= 0; i--) {
int arg_len = strlen(argv[i]) + 1; // 인자 길이 계산
if_->rsp = if_->rsp - arg_len; // 스택 포인터 이동
memcpy(if_->rsp, argv[i], arg_len); // 인자를 스택에 복사
arg_address[i] = if_->rsp; // 인자의 주소를 배열에 저장
}
while (if_->rsp % 8 != 0) {
if_->rsp--; // 스택 포인터를 1바이트씩 이동하여 단어 정렬을 위해 0으로 채움
*(uint8_t *)if_->rsp = 0;
}
for (int i = argc; i >= 0; i--) {
if_->rsp = if_->rsp - 8; // 스택 포인터 이동
if (i == argc)
memset(if_->rsp, 0, sizeof(char **)); // 마지막 주소는 NULL로 초기화
else
memcpy(if_->rsp, &arg_address[i], sizeof(char **)); // 인자의 주소를 스택에 복사
}
if_->R.rdi = argc; // RDI 레지스터에 argc 값을 설정
if_->R.rsi = if_->rsp; // RSI 레지스터에 스택 포인터 값을 설정
if_->rsp = if_->rsp - 8; // 스택 포인터 이동
memset(if_->rsp, 0, sizeof(void *)); // 반환 주소를 NULL로 초기화
}
argument_stack 함수는 PintOS에서 프로세스의 인자를 처리하여 스택에 저장하는 역할을 합니다. 주어진 argv 배열에 있는 인자들을 스택에 적절한 위치에 배치하고, 함수 호출 규약에 맞게 레지스터를 설정합니다.
함수의 동작을 요약하면 다음과 같습니다:
arg_address 배열은 인자들의 주소를 저장하기 위한 배열입니다. 최대 128개의 주소를 저장할 수 있습니다.
함수는 argv 배열에 있는 인자들을 역순으로 처리합니다. 각 인자의 길이를 계산하고, 스택 포인터를 인자의 길이만큼 감소시켜 해당 인자를 스택에 복사합니다. 그리고 arg_address 배열에 해당 인자의 주소를 저장합니다.
단어 정렬(word-align)을 위해 스택 포인터를 조정합니다. 스택 포인터를 8의 배수로 맞추기 위해 필요한 바이트 수만큼 스택 포인터를 감소시키고, 해당 위치에 0을 채웁니다.
다음으로 arg_address 배열을 역순으로 순회하면서 인자들의 주소를 스택에 저장합니다. 마지막으로는 NULL 값을 가리키는 주소를 스택에 저장합니다.
함수 호출 규약에 맞게 RDI 레지스터에 인자의 개수(argc)를 설정하고, RSI 레지스터에 스택 포인터의 값을 설정합니다.
마지막으로 반환 주소를 NULL로 초기화하기 위해 스택 포인터를 8만큼 감소시키고 해당 위치에 0을 채웁니다.
위의 과정을 통해 argument_stack 함수는 프로세스의 인자들을 스택에 적절하게 배치하여 프로그램이 실행될 때 인자들에 접근할 수 있도록 준비합니다

Argument Passing에 대해서 공부하고 있는데 이게 맞나 싶은 정도로 어려운 거 같습니다...
구현하거나 수정한 코드를 올리고 있지만 아직 테스트를 통과 못하고 있어서 언제든 수정될 수 있고 틀린 부분도 많을 거라 생각합니다...ㅎㅎ
그래도 포기하지 않고 끝까지 힘내보겠습니다! :)