Page 1 of 1

Implementing command line arguments, differences?

Posted: Sat Apr 21, 2012 11:25 pm
by casnix
I've been wondering about passing parameters from process to process...

In short (maybe) I know that functions can pass arguments such as:

Code: Select all

' ${Language = NASM}
SECTION .text
. . .
  foo:
    . . .
    push dummy_var
    call bar  ; bar(dummy_var)
    add esp, 4
    . . .
    . . .
  bar:  ; bar(byte uB)
    . . .
    mov eax, [esp+4]  ; (byte)eax = uB;
    . . .
    leave
    ret

I also am aware that passing arguments between/to a process(es) on Linux and Unix-like systems (and even Windows!) use the `esp` register to pass arguments.
Example, just for those who may not be familiar with this:

Code: Select all

' ${Language = NASM}
[GLOBAL main]
[EXTERN printf]

SECTION .data
  fmt:  db '%s',10,0

SECTION .text
  main:
    mov ecx, [esp+4]  ; argc
    mov edx, [esp+4*2]  ; argv

    push ecx  ; Because printf
    push edx  ;  -- likes to destroy the ecx and edx register contents :P

    push dword [edx]  ; argv[0]
    push dword fmt
    call printf  ; printf('%s\n', *argv[0]);
    add esp, 8

    leave
    ret

' Assembled and linked with a standard C-library that contains 'printf'
My curiosity has been piqued and I would like to know if anyone has written an OS (or knows of one) that uses a different method of parameter passing :D

Thank you,
Matt

Re: Implementing command line arguments, differences?

Posted: Sat Apr 21, 2012 11:42 pm
by gerryg400
I also am aware that passing arguments between/to a process(es) on Linux and Unix-like systems (and even Windows!) use the `esp` register to pass arguments.
No, I think you are getting confused. When main() is entered, its parameters are on the stack and can be accessed in the usual way, but in fact those parameters are copied there either by the operating system or by the start-up code that runs before main. The copy is necessary because in most operating systems, processes cannot access memory that belongs to another process.

Normally it's implemented like this

Code: Select all

(1) process A calls an exec* function. The args to the new process are passed to the exec* function which eventually translates to a system call.

(2) Inside the system call the kernel builds the new process (B) and copies the arguments from the A to B's new address space.

(3) Finally the kernel or the start-up code of B fiddles the stack of process B so that when main() is called it looks like the parameters were magically passed. 

Re: Implementing command line arguments, differences?

Posted: Sat Apr 21, 2012 11:59 pm
by casnix
Ahh...yeah. Well. Now to spend another 5 weeks trying to find something useful to say on here :P

Re: Implementing command line arguments, differences?

Posted: Sun Apr 22, 2012 2:05 am
by turdus
casnix wrote:My curiosity has been piqued and I would like to know if anyone has written an OS (or knows of one) that uses a different method of parameter passing :D
Yes. For example DOS passed argument list as a plain string after the program header (at offset cs:128 if I remember well).

Re: Implementing command line arguments, differences?

Posted: Sun Apr 22, 2012 11:25 am
by iansjack
Arguments are not always passed on the stack. The default in 64-bit mode with the x86_64 processors is to pass arguments in registers; it helps that there are twice as many register to play with than in 32-bit mode. You can choose whichever convention you want, but you will probably run into problems with your compiler which will produce code for the standard convention.

Re: Implementing command line arguments, differences?

Posted: Sun Apr 22, 2012 2:07 pm
by kammce
Hmmmm, well I just created a Shell for my OS. All I did was make a function that will read the first block of text (text that does not include a '\0' character or ' ' character) and checked if it was an actual command. Then I took all of the other text blocks and stored them for the program to use if it needed them.

Re: Implementing command line arguments, differences?

Posted: Wed Apr 25, 2012 10:03 am
by casnix
kammce wrote:Hmmmm, well I just created a Shell for my OS. All I did was make a function that will read the first block of text (text that does not include a '\0' character or ' ' character) and checked if it was an actual command. Then I took all of the other text blocks and stored them for the program to use if it needed them.
But where did you store them?

Re: Implementing command line arguments, differences?

Posted: Wed Apr 25, 2012 11:21 am
by Jezze
One of my ideas that I will probably also implement because somehow it just makes sense was to not send arguments at all and force all programs to read from stdin.

Re: Implementing command line arguments, differences?

Posted: Wed Apr 25, 2012 1:05 pm
by bluemoon
But if you follow the unix's pipe idea, you may need both stdin and arguments; or somehow allow to insert out of band data in stdin.
If you don't buy the whole pipe stuff, its another story.

Re: Implementing command line arguments, differences?

Posted: Wed Apr 25, 2012 2:56 pm
by Jezze
Now I'm embarrassed. The issue bluemoon pointed out was actually an issue I had thought about but had no good solution for... and then berkus just does the ninja-fly-by and enters the simple but now so obvious answer... When you are used to think in a certain way you just sometimes can't see the forrest for all the trees... #-o