Rust中的一个简单的三行Hello,World程序发出280行汇编文件以打印两个单词。同时,a pure assembly version of this program仅需要约15行。为什么Rust版本这么长?
这是在Mac OS上。
hello.rs
:
fn main() {
println!("hello world")
}
hello.s
(由rustc --emit=asm hello.rs
生成):
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 7
.private_extern __ZN3std2rt10lang_start17hb4e01c1e588bf694E
.globl __ZN3std2rt10lang_start17hb4e01c1e588bf694E
.p2align 4, 0x90
__ZN3std2rt10lang_start17hb4e01c1e588bf694E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $32, %rsp
leaq l___unnamed_1(%rip), %rax
movq %rdi, -8(%rbp)
leaq -8(%rbp), %rcx
movq %rcx, %rdi
movq %rsi, -16(%rbp)
movq %rax, %rsi
movq -16(%rbp), %rax
movq %rdx, -24(%rbp)
movq %rax, %rdx
movq -24(%rbp), %rcx
callq __ZN3std2rt19lang_start_internal17hcf96e32a124891dcE
movq %rax, -32(%rbp)
movq -32(%rbp), %rax
addq $32, %rsp
popq %rbp
retq
.cfi_endproc
.p2align 4, 0x90
__ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h275cd8632ff3ab7dE:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
callq *(%rdi)
callq __ZN54_$LT$$LP$$RP$$u20$as$u20$std..process..Termination$GT$6report17hf5e270b394827df3E
movl %eax, -4(%rbp)
movl -4(%rbp), %eax
addq $16, %rsp
popq %rbp
retq
.cfi_endproc
.p2align 4, 0x90
__ZN3std3sys4unix7process14process_common8ExitCode6as_i3217h7e671b2505e0c229E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movzbl (%rdi), %eax
popq %rbp
retq
.cfi_endproc
.p2align 4, 0x90
__ZN4core3fmt9Arguments6new_v117h39ef65f250941772E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
movq %rdi, %rax
movq $0, -16(%rbp)
movq %rsi, (%rdi)
movq %rdx, 8(%rdi)
movq -16(%rbp), %rdx
movq -8(%rbp), %rsi
movq %rdx, 16(%rdi)
movq %rsi, 24(%rdi)
movq %rcx, 32(%rdi)
movq %r8, 40(%rdi)
addq $16, %rsp
popq %rbp
retq
.cfi_endproc
.p2align 4, 0x90
__ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17h61f8ee8d3fead017E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
movq (%rdi), %rdi
callq __ZN4core3ops8function6FnOnce9call_once17h47f538be1b10688dE
movl %eax, -12(%rbp)
movl -12(%rbp), %eax
addq $16, %rsp
popq %rbp
retq
.cfi_endproc
.p2align 4, 0x90
__ZN4core3ops8function6FnOnce9call_once17h47f538be1b10688dE:
Lfunc_begin0:
.cfi_startproc
.cfi_personality 155, _rust_eh_personality
.cfi_lsda 16, Lexception0
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $48, %rsp
movq %rdi, -32(%rbp)
Ltmp0:
leaq -32(%rbp), %rdi
callq __ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h275cd8632ff3ab7dE
Ltmp1:
movl %eax, -36(%rbp)
jmp LBB5_1
LBB5_1:
jmp LBB5_2
LBB5_2:
movl -36(%rbp), %eax
addq $48, %rsp
popq %rbp
retq
LBB5_3:
jmp LBB5_4
LBB5_4:
movq -16(%rbp), %rdi
callq __Unwind_Resume
ud2
LBB5_5:
Ltmp2:
movq %rax, -16(%rbp)
movl %edx, -8(%rbp)
jmp LBB5_3
Lfunc_end0:
.cfi_endproc
.section __TEXT,__gcc_except_tab
.p2align 2
GCC_except_table5:
Lexception0:
.byte 255
.byte 255
.byte 1
.uleb128 Lcst_end0-Lcst_begin0
Lcst_begin0:
.uleb128 Ltmp0-Lfunc_begin0
.uleb128 Ltmp1-Ltmp0
.uleb128 Ltmp2-Lfunc_begin0
.byte 0
.uleb128 Ltmp1-Lfunc_begin0
.uleb128 Lfunc_end0-Ltmp1
.byte 0
.byte 0
Lcst_end0:
.p2align 2
.section __TEXT,__text,regular,pure_instructions
.p2align 4, 0x90
__ZN4core3ptr18real_drop_in_place17h0ab16307507408dbE:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
popq %rbp
retq
.cfi_endproc
.p2align 4, 0x90
__ZN54_$LT$$LP$$RP$$u20$as$u20$std..process..Termination$GT$6report17hf5e270b394827df3E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
xorl %edi, %edi
callq __ZN68_$LT$std..process..ExitCode$u20$as$u20$std..process..Termination$GT$6report17h03f2ed18f1614f97E
movl %eax, -4(%rbp)
movl -4(%rbp), %eax
addq $16, %rsp
popq %rbp
retq
.cfi_endproc
.p2align 4, 0x90
__ZN68_$LT$std..process..ExitCode$u20$as$u20$std..process..Termination$GT$6report17h03f2ed18f1614f97E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
movb %dil, -1(%rbp)
leaq -1(%rbp), %rdi
callq __ZN3std3sys4unix7process14process_common8ExitCode6as_i3217h7e671b2505e0c229E
movl %eax, -8(%rbp)
movl -8(%rbp), %eax
addq $16, %rsp
popq %rbp
retq
.cfi_endproc
.p2align 4, 0x90
__ZN5hello4main17hef70db39c48df377E:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $48, %rsp
leaq l___unnamed_2(%rip), %rax
xorl %ecx, %ecx
movl %ecx, %r8d
leaq -48(%rbp), %rdi
movq %rax, %rsi
movl $1, %edx
movl $8, %ecx
callq __ZN4core3fmt9Arguments6new_v117h39ef65f250941772E
leaq -48(%rbp), %rdi
callq __ZN3std2io5stdio6_print17hd8f597a6d310dad5E
addq $48, %rsp
popq %rbp
retq
.cfi_endproc
.globl _main
.p2align 4, 0x90
_main:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
movslq %edi, %rax
leaq __ZN5hello4main17hef70db39c48df377E(%rip), %rdi
movq %rsi, -8(%rbp)
movq %rax, %rsi
movq -8(%rbp), %rdx
callq __ZN3std2rt10lang_start17hb4e01c1e588bf694E
addq $16, %rsp
popq %rbp
retq
.cfi_endproc
.section __DATA,__const
.p2align 3
l___unnamed_1:
.quad __ZN4core3ptr18real_drop_in_place17h0ab16307507408dbE
.quad 8
.quad 8
.quad __ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h275cd8632ff3ab7dE
.quad __ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h275cd8632ff3ab7dE
.quad __ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17h61f8ee8d3fead017E
.section __TEXT,__const
l___unnamed_3:
.ascii "hello world\n"
.section __DATA,__const
.p2align 3
l___unnamed_2:
.quad l___unnamed_3
.asciz "\f\000\000\000\000\000\000"
.subsections_via_symbols
答案 0 :(得分:6)
在编译代码时,编译器可能会在不同方面做出很多潜在的取舍,例如:
大多数编译器将为您提供一些方法,以指定您希望如何权衡这些折衷。 rustc也不例外-您可以使用opt-level代码生成选项来指定所需的内容:
opt-level此标志可让您控制优化级别。
0:没有优化,也请打开cfg(debug_assertions)。
1:基本优化
2:一些优化
3:所有优化
s:优化二进制大小
z:优化二进制大小,但也关闭循环矢量化。
例如,您可以指定-C opt-level=3
以获得最佳性能(在大多数情况下,这也会增加编译时间)。
rustc选项-O
是-C opt-level=3
的简写。
根据@jbm提供的godbolt link,使用-O,您可以获得19行汇编。
还请注意,大多数人不会直接致电rustc,而是将货物用作构建控制工具。 cargo build
子命令允许您指定一个构建配置文件,该配置文件确定诸如所应用的优化级别之类的内容。 --release
标志调用适合发布版本的优化配置文件。