views:

80

answers:

3

This description is valid for Linux 32 bit: When a Linux program begins, all pointers to command-line arguments are stored on the stack. The number of arguments is stored at 0(%ebp), the name of the program is stored at 4(%ebp), and the arguments are stored from 8(%ebp).

I need the same information for 64 bit.

Edit: I have working code sample which shows how to use argc, argv[0] and argv[1]: http://cubbi.com/fibonacci/asm.html

.globl _start
_start:
    popq    %rcx        # this is argc, must be 2 for one argument
    cmpq    $2,%rcx
    jne     usage_exit
    addq    $8,%rsp     # skip argv[0]
    popq    %rsi        # get argv[1]
    call ...
...
}

It looks like parameters are on the stack. Since this code is not clear, I ask this question. My guess that I can keep rsp in rbp, and then access these parameters using 0(%rbp), 8(%rbp), 16(%rbp) etc. It this correct?

+1  A: 

I do believe what you need to do is check out the x86-64 ABI. Specifically, I think you need to look at section 3.2.3 Parameter Passing.

Dean Pucsek
This describes calling convention inside of the program. Process command line parameters may have their own rules. I need this specific information for Linux 64.
Alex Farber
A: 

Depensing wether that's Windows or Linux, that's different.

The Wikipedia page is quite good on this:

The registers RCX, RDX, R8, R9 are used for integer and pointer arguments (in that order left to right), and XMM0, XMM1, XMM2, XMM3 are used for floating point arguments. Additional arguments are pushed onto the stack (left to right). Integer return values (similar to x86) are returned in RAX if 64 bits or less. Floating point return values are returned in XMM0. Parameters less than 64 bits long are not zero extended; the high bits contain garbage.

In the Microsoft x64 calling convention, it's the caller's responsibility to allocate 32 bytes of "shadow space" on the stack right before calling the function (regardless of the actual number of parameters used), and to pop the stack after the call. The shadow space is used to spill RCX, RDX, R8, and R9.

Now, that you need the Command line arguments, they're essentially passed as normal arguments.

so for:

int main(int argc, const char* argv[])
{
    return 0;
}

The first parameter should be in RCX, second in RDX. Keep in mind, that second argument is basically const char** argv. Return code should be in RAX, when not using system interrupts.

polemon
polemon: the question is edited. Again: main function call convention may differ.
Alex Farber
I haven't found any info on that, but I'll check the next time I disassemble a program. Usually, I just do individual functions in assembly.
polemon
+2  A: 

It looks like section 3.4 Process Initialization, and specifically figure 3.9, in the already mentioned System V AMD64 ABI describes precisely what you want to know.

rkhayrov