Git Product home page Git Product logo

pintos-kaist's People

Contributors

agb94 avatar ahn9807 avatar eengblo avatar hestati63 avatar hyunwooj avatar junbongwe avatar shyeonn avatar sjchoi1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

pintos-kaist's Issues

User Programs: Argument Passing

Argument Passing

Setup the argument for user program in process_exec()

x86-64 Calling Convention

This section summarizes important points of the convention used for normal function calls on 64-bit x86-64 implementations of Unix. Some details are omitted for brevity. For more detail, you can refer System V AMD64 ABI.

The calling convention works like this:

  1. User-level applications use as integer registers for passing the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9.
  2. The caller pushes the address of its next instruction (the return address) on the stack and jumps to the first instruction of the callee. A single x86-64 instruction, CALL, does both.
  3. The callee executes.
  4. If the callee has a return value, it stores it into register RAX.
  5. The callee returns by popping the return address from the stack and jumping to the location it specifies, using the x86-64 RET instruction.

Consider a function f() that takes three int arguments. This diagram shows a sample stack frame and register state as seen by the callee at the beginning of step 3 above, supposing that f() is invoked as f(1, 2, 3). The initial stack address is arbitrary:

                             +----------------+
stack pointer --> 0x4747fe70 | return address |
                             +----------------+
RDI: 0x0000000000000001 | RSI: 0x0000000000000002 | RDX: 0x0000000000000003

Program Startup Details

The Pintos C library for user programs designates _start(), in lib/user/entry.c, as the entry point for user programs. This function is a wrapper around main() that calls exit() if main() returns:

void
_start (int argc, char *argv[]) {
    exit (main (argc, argv));
}

The kernel must put the arguments for the initial function on the register before it allows the user program to begin executing. The arguments are passed in the same way as the normal calling convention.

Consider how to handle arguments for the following example command: /bin/ls -l foo bar.

  1. Break the command into words: /bin/ls, -l, foo, bar.
  2. Place the words at the top of the stack. Order doesn't matter, because they will be referenced through pointers.
  3. Push the address of each string plus a null pointer sentinel, on the stack, in right-to-left order. These are the elements of argv. The null pointer sentinel ensures that argv[argc] is a null pointer, as required by the C standard. The order ensures that argv[0] is at the lowest virtual address. Word-aligned accesses are faster than unaligned accesses, so for best performance round the stack pointer down to a multiple of 8 before the first push.
  4. Point %rsi to argv (the address of argv[0]) and set %rdi to argc.
  5. Finally, push a fake "return address": although the entry function will never return, its stack frame must have the same structure as any other.

The table below shows the state of the stack and the relevant registers right before the beginning of the user program. Note that the stack grows down.

Address Name Data Type
0x4747fffc argv[3][...] 'bar\0' char[4]
0x4747fff8 argv[2][...] 'foo\0' char[4]
0x4747fff5 argv[1][...] '-l\0' char[3]
0x4747ffed argv[0][...] '/bin/ls\0' char[8]
0x4747ffe8 word-align 0 uint8_t[]
0x4747ffe0 argv[4] 0 char *
0x4747ffd8 argv[3] 0x4747fffc char *
0x4747ffd0 argv[2] 0x4747fff8 char *
0x4747ffc8 argv[1] 0x4747fff5 char *
0x4747ffc0 argv[0] 0x4747ffed char *
0x4747ffb8 return address 0 void (*) ()

RDI: 4 | RSI: 0x4747ffc0

In this example, the stack pointer would be initialized to 0x4747ffb8 As shown above, your code should start the stack at the USER_STACK, which is defined in include/threads/vaddr.h.

You may find the non-standard hex_dump() function, declared in <stdio.h>, useful for debugging your argument passing code.

Implement the argument passing.

Currently, process_exec() does not support passing arguments to new processes. Implement this functionality, by extending process_exec() so that instead of simply taking a program file name as its argument, it divides it into words at spaces. The first word is the program name, the second word is the first argument, and so on. That is, process_exec("grep foo bar") should run grep passing two arguments foo and bar.

Within a command line, multiple spaces are equivalent to a single space, so that process_exec("grep foo bar") is equivalent to our original example. You can impose a reasonable limit on the length of the command line arguments. For example, you could limit the arguments to those that will fit in a single page (4 kB). (There is an unrelated limit of 128 bytes on command-line arguments that the pintos utility can pass to the kernel.)

You can parse argument strings any way you like. If you're lost, look at strtok_r(), prototyped in include/lib/string.h and implemented with thorough comments in lib/string.c. You can find more about it by looking at the man page (run man strtok_r at the prompt).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.