gpt4 book ai didi

c++ - printf 与 cstdio 和 iostream 在汇编级别上的差异

转载 作者:太空宇宙 更新时间:2023-11-04 02:34:37 25 4
gpt4 key购买 nike

所以这个问题只是出于好奇。我有一些小程序:

#include <some_header>
void print(){ printf("abc"); } // don't care about main, I'm not gonna run it

然后我将它编译成汇编,一次是 some_header=>iostream 一次是 some_header=>cstdio 使用 gcc.godbolt.org(6.1 for x86_64)和 -O3 -pedantic -std=c++14。看看这个:

.LC0:
.string "abc"
print(): (iostream) or (both included)
movl $.LC0, %edi
xorl %eax, %eax
jmp printf
subq $8, %rsp
movl std::__ioinit, %edi
call std::ios_base::Init::Init()
movl $__dso_handle, %edx
movl std::__ioinit, %esi
movl std::ios_base::Init::~Init(), %edi
addq $8, %rsp
jmp __cxa_atexit
print(): (cstdio)
movl $.LC0, %edi
xorl %eax, %eax
jmp printf

它们之间存在显着差异,前三行是相同的,那么为什么 iostream 需要如此多的代码来清理或者这些行只是在做什么?或者只是说 Godbolt 在这个任务上不可靠?


此外,标准似乎不能保证 printf 可以从 iostream 访问,是否应该依赖于此?

最佳答案

在这两种情况下,您的 print 函数编译成几乎相同的汇编代码。您看到的其他行是初始化和取消初始化 iostream 库。如果您删除优化标志 -O3,您可能会清楚地看到这一点。这是包含 iostream 并关闭优化的完整 list 。

std::piecewise_construct:
.zero 1
.LC0:
.string "abc"
print():
pushq %rbp
movq %rsp, %rbp
movl $.LC0, %edi
movl $0, %eax
call printf
nop
popq %rbp
ret
__static_initialization_and_destruction_0(int, int):
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
cmpl $1, -4(%rbp)
jne .L4
cmpl $65535, -8(%rbp)
jne .L4
movl std::__ioinit, %edi
call std::ios_base::Init::Init()
movl $__dso_handle, %edx
movl std::__ioinit, %esi
movl std::ios_base::Init::~Init(), %edi
call __cxa_atexit
.L4:
nop
leave
ret
pushq %rbp
movq %rsp, %rbp
movl $65535, %esi
movl $1, %edi
call __static_initialization_and_destruction_0(int, int)
popq %rbp
ret

关于c++ - printf 与 cstdio 和 iostream 在汇编级别上的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39113490/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com