Согласно 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, перекладываются из регистров в память, и потом уже используются...
Это - что, шутка такая? (:
Почему не юзаются непосредственно регистры?