Согласно x86_64 ABI (http://www.x86-64.org/documentation/abi.pdf) параметры в C-функцию передаются через регистры... Отлично! Однако, допустим, есть следующий стартап код (test.s):
.text
.globl _start
_start:
xorq %rbp, %rbp		# set frame pointer to zerro, as per abi
popq	%rdi				# %rdi = argc
movq	%rsp, %rsi		# %rsi = argv
movq	%rdi, %rax
incq	%rax
shlq	$3, %rax
movq	%rsp, %rdx
addq	%rax, %rdx		# %rdx = arge
andq	$-16, %rsp		# align stack pointer to 16 bytes
pushq	%rax				# garbage (8 bytes)
pushq	%rsp				# stack pointer (8 bytes)
call main
movq %rax, %rdi		# %rax - retvalue
movq $60, %rax			# 60 - exit syscall number
syscall
Также есть функция main (test.c):
int main( int argc, char** argv, char** arge ) {
	int i;
	for( i=0; arge[i]; ++i );
	return i;
}
Далее компилируем, убираем лишнее и дизассемблируем:
$ gcc -nostdinc -nostdlib -fno-builtin -o test test.s test.c
$ strip ./test
$ objdump -d ./test
Получаем следующий дамп:
./test:     file format elf64-x86-64
Disassembly of section .text:
00000000004000b0 <.text>:
# _start:
  4000b0:       48 31 ed                xor    %rbp,%rbp
  4000b3:       5f                      pop    %rdi
  4000b4:       48 89 e6                mov    %rsp,%rsi
  4000b7:       48 89 f8                mov    %rdi,%rax
  4000ba:       48 ff c0                inc    %rax
  4000bd:       48 c1 e0 03             shl    $0x3,%rax
  4000c1:       48 89 e2                mov    %rsp,%rdx
  4000c4:       48 01 c2                add    %rax,%rdx
  4000c7:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
  4000cb:       50                      push   %rax
  4000cc:       54                      push   %rsp
# call main
  4000cd:       e8 0e 00 00 00          callq  0x4000e0
  4000d2:       48 89 c7                mov    %rax,%rdi
  4000d5:       48 c7 c0 3c 00 00 00    mov    $0x3c,%rax
  4000dc:       0f 05                   syscall
  4000de:       90                      nop
  4000df:       90                      nop
# main
  4000e0:       55                      push   %rbp
  4000e1:       48 89 e5                mov    %rsp,%rbp
# !!! move parameters back to memory
  4000e4:       89 7d ec                mov    %edi,0xffffffffffffffec(%rbp)
  4000e7:       48 89 75 e0             mov    %rsi,0xffffffffffffffe0(%rbp)
  4000eb:       48 89 55 d8             mov    %rdx,0xffffffffffffffd8(%rbp)
  4000ef:       c7 45 fc 00 00 00 00    movl   $0x0,0xfffffffffffffffc(%rbp)
  4000f6:       eb 04                   jmp    0x4000fc
  4000f8:       83 45 fc 01             addl   $0x1,0xfffffffffffffffc(%rbp)
  4000fc:       8b 45 fc                mov    0xfffffffffffffffc(%rbp),%eax
  4000ff:       48 98                   cltq
  400101:       48 c1 e0 03             shl    $0x3,%rax
  400105:       48 03 45 d8             add    0xffffffffffffffd8(%rbp),%rax
  400109:       48 8b 00                mov    (%rax),%rax
  40010c:       48 85 c0                test   %rax,%rax
  40010f:       75 e7                   jne    0x4000f8
  400111:       8b 45 fc                mov    0xfffffffffffffffc(%rbp),%eax
  400114:       c9                      leaveq
  400115:       c3                      retq
Из которого видно, что параметры, переданные в функцию main, перекладываются из регистров в память, и потом уже используются...
Это - что, шутка такая? (:
Почему не юзаются непосредственно регистры?

