Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
gcc生成的x86_64汇编代码中的xorl%eax,%eax_Gcc_Assembly_X86 64 - Fatal编程技术网

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