사용자 스택에 argv가 배치되는 순서 (x86-64 기준)
⸻
argc = 3
argv = {"./program", "arg1", "arg2", NULL}
⸻
스택에 저장되는 내용 (높은 주소 → 낮은 주소)
/bin/ls -l foo bar
맞음?
⸻
레지스터 설정
• %rdi = argc
• %rsi = &argv[0]
→ 즉, argv의 시작 주소가 들어감
왜?
유저 프로그램에서 main():
int main (int argc, char **argv) {
...
}
⸻
////////////////////////////////////////////////////////////////////////
//parsing
char *argv[64];
int argc=0;
char *token;
char *save_pointer;
token=strtok_r(file_name, " ", &save_pointer); //첫 번째 토큰 추출
//나머지 토큰 추출 반복
while(token !=NULL) { //"args-many"
argv[argc]=token;
token=strtok_r(NULL, " ", &save_pointer);
argc++;
}
/* And then load the binary */
success = load (file_name, &_if);
/* If load failed, quit. */
if (!success){
palloc_free_page (file_name);
return -1;
}
palloc_free_page (file_name); 을
success가 아닐때 넣어야하는데 밖에 넣어서 kernel panic이 계속 일어남
//////////////////////////////////////////
void **start_p = &_if.rsp;
argument_stack(argv, argc, start_p);
_if.R.rdi=argc;
_if.R.rsi=(uint64_t)*start_p+sizeof(void*);
// hex_dump(_if.rsp, _if.rsp, USER_STACK - (uint64_t)*start_p, true);
hex_dump: 디버깅할 시 스택의 구조를 보여줌
void argument_stack(char **argv, int argc, void **rsp){
for (int i=argc-1; i>=0; i--){
int argv_len=strlen(argv[i]); //문자열은 널문자를 포함해서 역순으로 복사
for(int j =argv_len; j>=0;j--){
char argv_char= argv[i][j]; //push
(*rsp)--; //rsp를 한 바이트씩 감소
//rsp가 가리키는 위치에 문자 저장
char *tmp=(char *)(*rsp);
*tmp = argv_char;
}
argv[i] = (char *) *rsp; // 문자열이 복사된 주소를 argv[i]에 저장
}
//word-align padding
int pad=(uint64_t)*rsp %8;
if (pad > 0){
pad=8-pad;
for (int k=0; k<pad;k++){
(*rsp)--;
*(uint8_t *)(*rsp)=0;
}
}
(*rsp)-=sizeof(char*);
*(char**)(*rsp)=NULL;
for (int i=argc-1; i>=0; i--){
(*rsp)-=sizeof(char*);
*(char**)(*rsp)=argv[i];
}
(*rsp) -= sizeof(void *);
*(void **)(*rsp) = 0;
}
pintos --fs-disk=10 -p tests/userprog/args-single:args-single -- -q -f run 'args-single onearg'

맞냐고 물어보면 어떡해요 이거보고 공부하늗네