gcc生成的x86_64汇编代码中的xorl%eax,%eax
我在集会上是个十足的傻瓜,只是随便看看发生了什么事。总之,我写了一个非常简单的函数:gcc生成的x86_64汇编代码中的xorl%eax,%eax,gcc,assembly,x86-64,Gcc,Assembly,X86 64,我在集会上是个十足的傻瓜,只是随便看看发生了什么事。总之,我写了一个非常简单的函数: void multA(double *x,long size) { long i; for(i=0; i<size; ++i){ x[i] = 2.4*x[i]; } } 我明白了: .file "fun.c" .text .p2align 4,,15 .globl multA .type multA, @function multA
void multA(double *x,long size)
{
long i;
for(i=0; i<size; ++i){
x[i] = 2.4*x[i];
}
}
我明白了:
.file "fun.c"
.text
.p2align 4,,15
.globl multA
.type multA, @function
multA:
.LFB34:
.cfi_startproc
testq %rsi, %rsi
jle .L1
movsd .LC0(%rip), %xmm1
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L3:
movsd (%rdi,%rax,8), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, (%rdi,%rax,8)
addq $1, %rax
cmpq %rsi, %rax
jne .L3
.L1:
rep
ret
.cfi_endproc
.LFE34:
.size multA, .-multA
.section .rodata.cst8,"aM",@progbits,8
.align 8
.LC0:
.long 858993459
.long 1073951539
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits
除了行xorl%eax,%eax
之外,汇编输出对我来说(大部分)是有意义的。通过谷歌搜索,我推断这只是为了将%eax
设置为零,在这种情况下,它对应于我的迭代器long I代码>
但是,除非我弄错了,%eax
是一个32位寄存器。因此,在我看来,这实际上应该是xorq%rax,%rax
,特别是因为它包含一个64位长的int。此外,在代码的更深处,它实际上使用64位寄存器%rax
进行迭代,在xorl%eax%eax
之外,它永远不会被初始化,这似乎只是将寄存器的低32位归零
我错过什么了吗
另外,出于好奇,为什么底部有两个.long
常量?第一个数字,858993459
等于2.4
的双浮点表示,但我不知道第二个数字是什么,也不知道它为什么在那里
我推测这只是为了将%eax设置为零
对
在本例中,它对应于我的迭代器longi
否。您的i
在声明中未初始化。严格地说,该操作对应于for循环中的i=0
表达式
但是,除非我弄错了,%eax是一个32位寄存器。所以在我看来,这实际上应该是xorq%rax%rax,特别是因为它包含一个64位长的int
但是清除寄存器中较低的双字会清除整个寄存器。这不是直观的,而是隐含的。仅回答第二部分:。long
表示32位,两个积分常数并排构成双2.4的IEEE-754表示:
Dec: 1073951539 858993459
Hex: 0x40033333 0x33333333
400 3333333333333
S+E Mantissa
指数偏移1023,因此实际指数为0x400−1023=1. 尾数中的前导“一”是隐含的,因此它是21×0b1.001100110011。。。(您认识到这个周期性扩展为3/15,即0.2。当然,2×1.2=2.4。)您的平台上的sizeof(long)
是什么?@KerrekSB-Ah OK。我明白了,对不起。@KerrekSB顺便说一下,检查该值,1073951539
是2.05
的32位IEEE-754表示形式。这两个长度都是64位浮点的一部分。这是一个标准问答。谢谢。我想一定是这样,但我在任何地方都找不到记录在案的。就像我说的,我是一个彻头彻尾的傻瓜。今天学到了一些新东西,不知道清除EAX会清除RAX。然而,我想知道“清除较低的字”是否是正确的说法,AMD64体系结构上的字大小不是64位吗?@us2012“字大小”的通常定义被Intel忽略了。一个字总是16位。32=dword,64=qword。@us2012我不是一个优秀的硬件黑客,所以你可能实际上是对的,但在我的阅读中(除了我不总是在一般情况下使用的挑剔的C术语),byte=1字节或8位,word=2字节或16位,double-word=4字节或32位,quad-word=8字节或64位。@mrip没问题,正如我所说的,这并不明显,因此这是一个合法的初学者问题。(我很少这么说,所以要骄傲:P)啊哈。谢谢这很有道理。因为我不注意类型是double
,它是64位长+1.@H2CO3:你基本上是对的,但指数的大小应该会给你提示:-)
Dec: 1073951539 858993459
Hex: 0x40033333 0x33333333
400 3333333333333
S+E Mantissa