Dav*_*eri 0 c assembly type-conversion
遵循这个主题 ......
对于这段代码:
#include <stdio.h>
int main(void)
{
int i;
size_t u;
for (i = 0; i < 10; i++) {
u = (size_t)i;
printf("i = %d, u = %zu\n", i, u);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
程序集中的输出是:
编辑:用-O2编译
.file "demo.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "i = %d, u = %zu\n"
.section .text.startup,"ax",@progbits
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB3:
.cfi_startproc
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
xorl %ebx, %ebx
.p2align 4,,10
.p2align 3
.L2:
movq %rbx, %rdx
movl %ebx, %esi
xorl %eax, %eax
movl $.LC0, %edi
addq $1, %rbx
call printf
cmpq $10, %rbx
jne .L2
xorl %eax, %eax
popq %rbx
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE3:
.size main, .-main
.ident "GCC: (Debian 4.7.2-5) 4.7.2"
.section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)
转换是否u = (size_t)i;消耗额外的周期?
是的,因为代码已发布,当然.您的转换位于:
movl -4(%rbp), %eax
cltq
movq %rax, -16(%rbp)
Run Code Online (Sandbox Code Playgroud)
当然,这段代码没有经过优化,所以这不是一个非常公平的比较.如果你用优化编译,编译器可能会意识到值始终为正,只是做无论从任何寄存器保存一个举动i,以%rdx保持第三个参数.
编辑:
如所怀疑的,优化代码中基本上没有开销.在这种情况下,编译器转换的循环来计数u,并从中获得i从u而不是周围的其他方法,所以%rbx被用于循环,和的值i是在运用%ebx,这是低32位%rbx-所以有在这个例子中没有开销.我强调这一点,因为很可能会有其他情况下转换int为size_t将会受到惩罚.这完全取决于具体情况.