본문 바로가기

KAIST PINTOS

argument passing

수정한 순서대로 기록

 

 

tid_t process_create_initd (const char *file_name)

 

새로운 스레드를 생성함으로써 유저 프로그램 initd를 시작한다. 새로운 스레드는 process_create_inid()가 반환하기 전에 PRI_DEFAULT로 시작되어 스케줄링되고, 종료될 수도 있다. initd의 스레드 아이디를 반환하거나 TID_ERROR를 발생시킨다. 

 

 

int process_exec(void *f_name)

내부에 파라미터로 들어온 f_name을 file_name 선언해서 malloc 해주고, free 해줌.

 

load

 

argv malloc 해줬음 이따가 free 해줘야함. 

arg_addr palloc 해줬음 이따가 palloc_free_page 해줘야함.

 

foo a b c 라고 커맨드라인에 입력해줬다고 하자.

argv에는 아래와 같이 저장되어 있을 것이고, argc = 4일 것이다. 

argv[0] argv[1] argv[2] argv[3]
foo a b c

스택은 위에서 아래로 성장하는 구조인데, 그러면 argv[argc - 1]부터 위에서 아래로 쌓아주면 된다. argv 요소의 길이를 argv_len에 받아(널문자 포함한 길이로 받아야한다) rsp를 해당 길이만큼 내려주고 memcpy 해준다. arg_addr에 해당 rsp 주소를 저장해준다. 그러면 argv[i]에는 argv[i]을 넣어준 주소가 저장돼있을 것이다. 

 

	for (int i = argc - 1; i > -1; k--){
		int argv_len = strlen(argv[k]) + 1; // "\0" 포함한 길이
		if_->rsp -= argv_len;
		memcpy(if_->rsp, argv[k], argv_len);
		arg_addr[k] = if_->rsp;	//addr 저장
	}

 

argument를 저장했으면 word_align으로 주소값이 8로 나눠떨어지게 만들어준다. 

 

	uintptr_t word_align = if_->rsp % 8;
	if_->rsp -= word_align;
	memset((void *)if_->rsp, 0, word_align);

 

그 다음은 8바이트(char * size)만큼 0으로 채워준다. 

 

	if_->rsp -= 8;
	memset(if_->rsp, 0, 8);

 

이제 argument가 저장되어있는 주소 값을 넣어줘야한다. 

이것 또한 argv[i]에서 i = argc - 1 부터 0까지 넣어줘야한다. 순서에 주의하장

	for (int j = argc - 1; j > -1; j--){
		if_->rsp -= 8;
		memcpy((char *)if_->rsp, &arg_addr[j], 8);
	}

 

return address를 넣어주자. 

	if_->rsp -= 8;
	memset((char *)if_->rsp, 0, 8);

 

마지막으로 rsi와 rdi 레지스터에 argv[0]이 저장된 주소를 넣어준 곳의 주소!와 argument 개수(argc - 1)를 각각 넣어주자. 가장 위에 있는 표를 기준으로 RDI: 4 | RSI: 0x4747ffc0가 되어야한다. 

 

아까 malloc과 palloc을 이용해서 할당해준 메모리들을 free 해줘야한다. 위치가 신경쓰이네 이전에 코드를 짤 떄는 항상 success = done; 바로 위에 free를 해줬었는데, 그러면 중간에 에러가 떠서 goto: done으로 빠지는 경우에는 할당된 메모리들이 free되지 않는거 아닌가? 하는 생각이 들었다. done: 바로 밑에 아래같은 메세지가 써져있다. 

  /* We arrive here whether the load is successful or not. */
 
load가 성공하든 말든 load()함수가 끝나기 전에 항상 이곳을 거친다는 것 같은데, 그럼 load()가 시작되는 부분에 할당을 해줬고, 이것을 깨끗하게 정리해주고싶다면 done: 뒤에 써야되는거 아닐까?

 

 

hex_dump()를 이용해서 argument passing이 잘 되었는지 확인해보자. 

	hex_dump(if_->rsp, if_->rsp, USER_STACK - if_->rsp, true);

pintos -v -k -T 60 -m 20   --fs-disk=10 -p tests/userprog/args-single:args-single -- -q   -f run 'args-single hey'

pintos -v -k -T 60 -m 20   --fs-disk=10 -p tests/userprog/args-single:args-single -- -q   -f run 'args-single a b c d e f'

이런식으로 나오면 일단 된 것 같다^0^

'KAIST PINTOS' 카테고리의 다른 글

syscall.c  (0) 2022.02.13
Process.c  (0) 2022.02.13
Project 2 디버깅  (0) 2022.02.07
system call  (0) 2022.01.21
PROJECT 1 - Alarm Clock, Priority Scheduling  (0) 2022.01.20