๐Ÿ“€ KAIST:PINTOS | Implementation | Argument Passing

์ด์ˆœ๊ฐ„ยท2025๋…„ 5์›” 18์ผ

KAIST:PINTOS

๋ชฉ๋ก ๋ณด๊ธฐ
14/23

1. Argument Passing์˜ ๋ชฉ์ 

์œ ์ € ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ช…๋ น์–ด๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜์ž.

args-many a b c d e f g

๊ทธ๋Ÿผ ์œ ์ € ํ”„๋กœ์„ธ์Šค ๋‚ด๋ถ€์˜ main(int argc, char **argv)๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ’์„ ๋ฐ›์•„์•ผ ํ•œ๋‹ค.

argc == 8
argv[0] == "args-many"
argv[1] == "a"
argv[2] == "b"
...
argv[7] == "g"

์ด๊ฒƒ์„ ์œ„ํ•ด Pintos๋Š” ์ปค๋„์—์„œ ๋ฌธ์ž์—ด์„ ํŒŒ์‹ฑํ•˜๊ณ , ์ธ์ž๋“ค์„ ์Šคํƒ์— pushํ•˜์—ฌ ์œ ์ € ํ”„๋กœ๊ทธ๋žจ์ด main()์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค˜์•ผ ํ•œ๋‹ค. ์ด ๋ชจ๋“  ๊ณผ์ •์„ Argument Passing์ด๋ผ๊ณ  ํ•œ๋‹ค.


2. ์ „์ฒด ํ๋ฆ„ ์š”์•ฝ

๋‹จ๊ณ„ํ•จ์ˆ˜์œ„์น˜๋‚ด์šฉํ˜„์žฌ ์ƒํƒœ
1process_exec()userprog/process.c์ „๋‹ฌ๋ฐ›์€ ๋ฌธ์ž์—ด ํŒŒ์‹ฑ (strtok_r ์ด์šฉ)๊ตฌํ˜„ ์™„๋ฃŒ
2load()userprog/process.c์‹คํ–‰ ํŒŒ์ผ ๋กœ๋”ฉ, ์Šคํƒ ๊ณต๊ฐ„ ์ƒ์„ฑ (setup_stack)๊ตฌํ˜„ ์™„๋ฃŒ
3setup_stack()userprog/process.c์œ ์ € ์Šคํƒ ํŽ˜์ด์ง€ ํ• ๋‹น, rsp ์ดˆ๊ธฐํ™”๊ตฌํ˜„ ์™„๋ฃŒ
4argument_stack()userprog/process.c์ธ์ž push ๋ฐ rsp ์„ค์ •๊ตฌํ˜„ ํ•„์š”
5do_iret()userprog/process.c์œ ์ € ์ฝ”๋“œ ์ง„์ž…๊ตฌํ˜„ ์™„๋ฃŒ (์ˆ˜์ • ํ•„์š” ์—†์Œ)

3. ํ˜„์žฌ๊นŒ์ง€ ๊ตฌํ˜„ํ•œ ๋‚ด์šฉ

ํŒŒ์ผ: userprog/process.c

์œ„์น˜: process_exec()
  1. ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ธ์ž ๋ฌธ์ž์—ด ํŒŒ์‹ฑ์„ ์™„๋ฃŒํ•จ
char *argv[64];
int argc=0;

char *token;
char *save_pointer;

token = strtok_r(file_name, " ", &save_pointer);

while (token != NULL) {
    argv[argc] = token;
    token = strtok_r(NULL, " ", &save_pointer);
    argc++;
}
  1. ํŒŒ์‹ฑ๋œ ๊ฒฐ๊ณผ๋ฅผ GDB์—์„œ ํ™•์ธํ•œ ๊ฒฐ๊ณผ:
argc == 8
argv[0] == "args-many"
argv[1] == "a"
...
argv[7] == "g"
  1. ์ด ์ƒํƒœ๊นŒ์ง€๋Š” ์™„๋ฒฝํ•˜๊ฒŒ ํŒŒ์‹ฑ์ด ์™„๋ฃŒ๋จ

4. ๋‹ค์Œ ๋‹จ๊ณ„: argument_stack ๊ตฌํ˜„

argv[]๋ฅผ ์ด์šฉํ•ด์„œ ์œ ์ € ์Šคํƒ์— ๋‹ค์Œ ๋‚ด์šฉ์„ ์ •ํ™•ํžˆ ๋„ฃ์–ด์ค˜์•ผ ํ•œ๋‹ค.

  • ์ธ์ž ๋ฌธ์ž์—ด๋“ค (๋ฌธ์ž์—ด ๊ฐ’๋“ค)
  • ๊ฐ ๋ฌธ์ž์—ด๋“ค์˜ ์ฃผ์†Œ (argv[i])
  • argv[] ๋ฐฐ์—ด ์ž์ฒด์˜ ์ฃผ์†Œ
  • argc
  • fake return address (0)

5. argument_stack() ํ•จ์ˆ˜ ์ž‘์„ฑ๋ฒ•

ํŒŒ์ผ: userprog/process.c

ํ•จ์ˆ˜ ์„ ์–ธ ์ด๋ฏธ ์žˆ์Œ:

void argument_stack(char **argv, int argc, void **rsp);

ํ•ด๋‹น ํ•จ์ˆ˜ ๊ตฌํ˜„: ์•„๋ž˜ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋จ

void argument_stack(char **argv, int argc, void **rsp) {
    char *arg_addr[64];

    // ์ธ์ž ๋ฌธ์ž์—ด๋“ค์„ ์Šคํƒ์— push (๋’ค์—์„œ๋ถ€ํ„ฐ)
    for (int i = argc - 1; i >= 0; i--) {
        int len = strlen(argv[i]) + 1;
        *rsp -= len;
        memcpy(*rsp, argv[i], len);
        arg_addr[i] = *rsp; // ๋ณต์‚ฌ๋œ ์ฃผ์†Œ ์ €์žฅ
    }

    // 8๋ฐ”์ดํŠธ ์ •๋ ฌ
    while ((uintptr_t)(*rsp) % 8 != 0) {
        *rsp -= 1;
        *(uint8_t *)(*rsp) = 0;
    }

    // ๊ฐ argv[i] ์ฃผ์†Œ push
    *rsp -= sizeof(char *);
    *(char **)(*rsp) = NULL; // argv[argc] = NULL

    for (int i = argc - 1; i >= 0; i--) {
        *rsp -= sizeof(char *);
        *(char **)(*rsp) = arg_addr[i];
    }

    // argv ํฌ์ธํ„ฐ ์ €์žฅ
    char **argv_start = *rsp;
    *rsp -= sizeof(char **);
    *(char ***)(*rsp) = argv_start;

    // argc ์ €์žฅ
    *rsp -= sizeof(int);
    *(int *)(*rsp) = argc;

    // fake return address
    *rsp -= sizeof(void *);
    *(void **)(*rsp) = 0;
}

6. ์ด ํ•จ์ˆ˜ ํ˜ธ์ถœ ์œ„์น˜

ํŒŒ์ผ: userprog/process.c

ํ•จ์ˆ˜: process_exec()

load()๊ฐ€ ๋๋‚œ ์งํ›„ ๋‹ค์Œ ์ค„์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋จ

argument_stack(argv, argc, &(_if.rsp));

์ตœ์ข… ๊ตฌ์กฐ๋Š” ์ด๋ ‡๊ฒŒ ๋จ:

success = load (file_name, &_if);
palloc_free_page (file_name);
if (!success)
    return -1;

// argument_stack ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ถ”๊ฐ€
argument_stack(argv, argc, &(_if.rsp));

// ์œ ์ € ํ”„๋กœ์„ธ์Šค๋กœ ์ง„์ž…
do_iret(&_if);

7. ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ•

๋‹ค์Œ ๋ช…๋ น์–ด๋กœ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋‹ค:

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

์ •์ƒ์ ์œผ๋กœ ํ†ต๊ณผ๋˜๋ฉด ์ถœ๋ ฅ์—์„œ ๊ฐ ์ธ์ž๊ฐ€ ์ž˜ ์ถœ๋ ฅ๋œ๋‹ค.


8. GDB ๋””๋ฒ„๊น… ํŒ

  • GDB์—์„œ ์Šคํƒ ํฌ์ธํ„ฐ๋ฅผ ๋”ฐ๋ผ๊ฐ€๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉ
b process_exec
c
x/s argv[0]
x/s argv[1]
...
x/40cb file_name
print argc
x/20x $rsp
  • x/s, x/20x, print argc ๋“ฑ์€ ๋ฌธ์ž์—ด ํ™•์ธ๊ณผ ๋ฉ”๋ชจ๋ฆฌ ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๋Š” ๋ฐ ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค.

9. ๋งˆ๋ฌด๋ฆฌ

  • ํŒŒ์ผ๋ช…๊ณผ ์ธ์ž ๋ฌธ์ž์—ด ํŒŒ์‹ฑ: ์™„๋ฃŒ
  • load() ๋ฐ setup_stack(): ์™„๋ฃŒ
  • GDB๋กœ ํŒŒ์‹ฑ ๊ฒ€์ฆ: ์™„๋ฃŒ

๋‚จ์€ ๊ฑด ์˜ค์ง ํ•˜๋‚˜:

  • argument_stack() ๊ตฌํ˜„๊ณผ ํ˜ธ์ถœ

์ด๊ฑธ ์™„๋ฃŒํ•˜๋ฉด, ๋ชจ๋“  Argument Passing ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋Š” ํ†ต๊ณผ??

profile
์„œํˆด์ง€์–ธ์ • ๋Š˜ ํ–‰๋™์ด ๋จผ์ €์ด๊ธฐ๋ฅผ

4๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2025๋…„ 5์›” 18์ผ

ใ„ฑใ……ใ„ฑใ……

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ
comment-user-thumbnail
2025๋…„ 5์›” 19์ผ

When debugging my OS project, I kept failing stack tests until I realizedโ€”proper argument passing means nothing without system calls! That "No" verdict haunted me until I discovered https://wacky-flip-game.com/. Their wacky flip approach to low-level coding (exit() implementations especially) became my secret weapon. Suddenly, stack frames aligned like magic. Turns out, even perfect assembly crashes without the right syscallsโ€”lesson

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ
comment-user-thumbnail
2025๋…„ 5์›” 19์ผ

When debugging my OS project, I kept failing stack tests until I realizedโ€”proper argument passing means nothing without system calls! That "No" verdict haunted me until I discovered https://wacky-flip-game.com/. Their wacky flip approach to low-level coding (exit() implementations especially) became my secret weapon. Suddenly, stack frames aligned like magic. Turns out, even perfect assembly crashes without the right syscallsโ€”lesson

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ
comment-user-thumbnail
2025๋…„ 5์›” 19์ผ

When debugging my OS project, I kept failing stack tests until I realizedโ€”proper argument passing means nothing without system calls! That "No" verdict haunted me until I discovered https://wacky-flip-game.com/. Their wacky flip approach to low-level coding (exit() implementations especially) became my secret weapon. Suddenly, stack frames aligned like magic. Turns out, even perfect assembly crashes without the right syscallsโ€”lesson

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ