Linux 64.
GCC 4.8.2 (with -O3 -march=native)
The x86_64 abi under my left hand, opened at page 21.
int main (int argc, char ** argv) {
printf("%d %s\n", atoi(argv[2]),argv[1] );
}
(notice that the compiler replaced atoi with strtol by itself)
...
movl $10, %edx
movq 16(%rsi), %rdi
movq 8(%rsi), %rbx
xorl %esi, %esi
call strtol
movl $.LC0, %edi
movq %rbx, %rdx
movl %eax, %esi
xorl %eax, %eax
call printf
xorl %eax, %eax
popq %rbx
...
%rcx
should be reserved for the 4th input integer argument.
strtol
has 3 input args (respectively registers %rdi
, %rsi
, %rdx
) and one return, %eax
.
Why then is %rcx
clobbered ?
This code won't make it :
...
movl $10, %edx
movq 16(%rsi), %rdi
movq 8(%rsi), %rcx <-- look I replaced with %ecx
xorl %esi, %esi
call strtol
movl $.LC0, %edi
movq %rcx, %rdx <-- look I replaced with %ecx
movl %eax, %esi
xorl %eax, %eax
call printf
xorl %eax, %eax
popq %rbx
...
Thanks
In each calling convention I know there are some registers that may be modified by the called function and some which must not be modified.
In 32-bit programs ecx may be modified while ebx must not be modified - or, to be more exact - must be re-stored before returning. For 64-bit programs this rule seems to be the same.
Indeed most functions modify most registers; for this reason there is a "popq %rbx" at the end of the code you posted because rbx must not be modified by the function. rcx may be modified and strtol obviously does that!