C 从大小\u t到整数的转换
接下来 对于这段代码:C 从大小\u t到整数的转换,c,assembly,type-conversion,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; } 是转换u=(size\u t)i消耗额外的周期?是的,因为代码已发布,当然。您的转换在这里:
#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;
}
是转换
u=(size\u t)i代码>消耗额外的周期?是的,因为代码已发布,当然。您的转换在这里:
movl -4(%rbp), %eax
cltq
movq %rax, -16(%rbp)
当然,这段代码是未优化的,所以这不是一个非常公平的比较。如果您使用优化方法编译它,编译器可能会意识到这些值总是正的,并且只需从存放第三个参数的i
寄存器移到存放第三个参数的%rdx
编辑:
正如所怀疑的那样,优化后的代码基本上没有开销。在这种情况下,编译器将循环转换为向上计数u
,并从u
派生i
,而不是反过来,因此%rbx
用于循环,i
的值仅使用%ebx
,这是%rbx
的较低32位-因此在本例中没有开销。我强调这一点,因为在其他情况下,从int
转换为size\u t
可能会受到惩罚。这完全取决于具体情况 是的,因为它将内部表示从32位更改为64位。
具体来说,
.L3:
movl -4(%rbp), %eax
cltq
movq %rax, -16(%rbp)
movq -16(%rbp), %rdx
读取i
,执行符号扩展并复制到%rdx
。我不确定为什么这个值必须通过堆栈——正如mats指出的,这看起来像是来自非优化编译器运行的代码
编辑
在优化的汇编代码中,循环计数器保持为更宽的数据类型。afair,mov
s寄存器之间的运行时周期wrt quad或dword没有差异(事实上,它们没有差异:请参见表C-16,参考。不确定这是否是您消耗周期的实际分配
我相信这是一项消耗生命周期的任务
比如说
在这个t1.c上
#include <stdio.h>
int main(void)
{
int i;
size_t u;
for (i = 0; i < 10; i++) {
printf("i = %d, u = %zu\n", i, u);
}
return 0;
}
在上述情况下,暂时不允许分配atall
第二个案例t2.c
#include <stdio.h>
int main(void)
{
int i;
size_t u;
for (i = 0; i < 10; i++) {
i = (size_t) u;
printf("i = %d, u = %zu\n", i, u);
}
return 0;
}
检查上面的陈述
movl 28(%esp), %eax
movl %eax, 24(%esp)
现在来看最后一个示例t3.c
#include <stdio.h>
int main(void)
{
int i;
int u;
for (i = 0; i < 10; i++) {
i = u;
printf("i = %d, u = %zu\n", i, u);
}
return 0;
}
现在,您可以观察t2和t3,并在这里看到差异,但每个拱门之间的差异确实不同,尽管看起来您并没有打开优化器,这使它成为一个无意义的练习。谢谢,汉斯,请参见编辑谢谢Mats,现在它在编译时启用了-O2标志(请参见编辑)谢谢,现在我明白了
.file "t2.c"
.section .rodata
.LC0:
.string "i = %d, u = %zu\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $0, 24(%esp)
jmp .L2
.L3:
movl 28(%esp), %eax
movl %eax, 24(%esp)
movl $.LC0, %eax
movl 28(%esp), %edx
movl %edx, 8(%esp)
movl 24(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
addl $1, 24(%esp)
.L2:
cmpl $9, 24(%esp)
jle .L3
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.4.6 20110731 (Red Hat 4.4.6-3)"
.section .note.GNU-stack,"",@progbits
movl 28(%esp), %eax
movl %eax, 24(%esp)
#include <stdio.h>
int main(void)
{
int i;
int u;
for (i = 0; i < 10; i++) {
i = u;
printf("i = %d, u = %zu\n", i, u);
}
return 0;
}
.file "t3.c"
.section .rodata
.LC0:
.string "i = %d, u = %zu\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $0, 24(%esp)
jmp .L2
.L3:
movl 28(%esp), %eax
movl %eax, 24(%esp)
movl $.LC0, %eax
movl 28(%esp), %edx
movl %edx, 8(%esp)
movl 24(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
addl $1, 24(%esp)
.L2:
cmpl $9, 24(%esp)
jle .L3
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.4.6 20110731 (Red Hat 4.4.6-3)"
.section .note.GNU-stack,"",@progbits