对于 Linux x86_64 上的 64 位 gcc -O3 (4.5.0),其内容为:cout
movl $11, %edx ; String length in EDX
movl $.LC0, %esi ; String pointer in ESI
movl $_ZSt4cout, %edi ; load virtual table entry of "cout" for "ostream"
call _ZSt16__ostream_insertIcSt11char_traits...basic_ostreamIT_T0_ES6_PKS3_l
对于 printf("Hello World")
movl $.LC0, %edi ; String pointer to EDI
xorl %eax, %eax ; clear EAX (maybe flag for printf=>no stack arguments)
call printf
这意味着,您的顺序完全取决于任何特定的
编译器实现,它的版本和可能的编译器选项。
您的编辑 状态,您使用 gcc 4.5.2(相当新)。
似乎 4.5.2 引入了额外的 64 位寄存器摆弄
无论出于何种原因,这个序列。它将 64 位 RAX 保存到 RDI
在将其归零之前 - 这绝对没有意义(至少对我而言)。
更有趣:3 参数调用序列(g++ -O1 -S source.cpp):
void c_proc()
{
printf("%s %s %s", "Hello", "World", "!") ;
}
void cpp_proc()
{
std::cout << "Hello " << "World " << "!";
}
导致(c_proc):
movl $.LC0, %ecx
movl $.LC1, %edx
movl $.LC2, %esi
movl $.LC3, %edi
movl $0, %eax
call printf
.LCx 是字符串,不涉及堆栈指针!
对于 cpp_proc:
movl $6, %edx
movl $.LC4, %esi
movl $_ZSt4cout, %edi
call _ZSt16__ostream_insertIcSt11char_traits...basic_ostreamIT_T0_ES6_PKS3_l
movl $6, %edx
movl $.LC5, %esi
movl $_ZSt4cout, %edi
call _ZSt16__ostream_insertIcSt11char_traits...basic_ostreamIT_T0_ES6_PKS3_l
movl $1, %edx
movl $.LC0, %esi
movl $_ZSt4cout, %edi
call _ZSt16__ostream_insertIcSt11char_traits...basic_ostreamIT_T0_ES6_PKS3_l
你现在明白这是怎么回事了。
问候
rbo