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
Assembly 为什么bool=bool的代码生成有差异?int:int_Assembly_X86_X86 64_Compiler Optimization - Fatal编程技术网

Assembly 为什么bool=bool的代码生成有差异?int:int

Assembly 为什么bool=bool的代码生成有差异?int:int,assembly,x86,x86-64,compiler-optimization,Assembly,X86,X86 64,Compiler Optimization,此代码 bool condSet(int cond, int a, int b) { return cond ? a : b; } …为gcc 6.3生成 test edx, edx setne al test edi, edi jne .L6 rep ret .L6: test esi, esi setne al ret 。。国际刑事法院第17号 test edi,

此代码

bool condSet(int cond, int a, int b) {
    return cond ? a : b;
}
…为gcc 6.3生成

    test    edx, edx
    setne   al 
    test    edi, edi
    jne     .L6
    rep ret
.L6:
    test    esi, esi
    setne   al
    ret
。。国际刑事法院第17号

    test      edi, edi
    cmovne    edx, esi
    mov       eax, 1
    test      edx, edx
    cmove     eax, edx
    ret       
..对于叮当声3.9

    test    edi, edi
    cmove   esi, edx
    test    esi, esi
    setne   al
    ret
对于一个代码模式,为什么我们会有这些我认为是常见的差异?它们都依赖于条件指令、setne、cmovne、cmove,但gcc也有一个分支,它们都使用不同的指令顺序和参数

编译器中的哪个过程负责生成此代码?是由于寄存器分配方式造成的差异;如何进行一般数据流分析;或者在生成代码时编译器模式是否与此模式匹配


代码和asm清单:

使用
test/cmov
策略,将返回类型更改为
int
将导致来自所有三个编译器的无分支代码

我猜gcc认为将条件的两边都布尔化太麻烦了,于是决定使用一个分支。也许它没有意识到这是相同的工作,而表达式实际上可以用另一种方式完成(选择正确的输入,然后将其布尔化)

它生成的代码会布尔化
b
,然后才测试条件并布尔化
a
。因此,当
cond
为true时,它实际上同时运行
test
/
setnz

这闻起来像是错过了一个优化错误。(或者是一个优化狂奔bug,它通过将返回类型应用于
?:
的两个输入,而不是仅应用于结果,从而击中了自己的脚)

报告为


在修复之前,您可以通过将其分为两个步骤:

bool condSet(int cond, int a, int b) {
  int tmp = cond ? a : b;       // better asm from gcc this way
  return tmp;
}

可能是因为不同的人编写了编译器代码。在形式上,向汇编程序的转换不是强制性的:可执行的C代码只需符合标准即可。所有这些都需要经过编译器优化设置。哪一关?C代码有一个预处理阶段,但编译器是一次性的。安娜·卡列尼娜有许多英文译本,但即使是基本句子,它们也使用不同的单词。你会认为对于一个普通的句子,他们会使用完全相同的词。@RaymondChen,@WeatherVane。抱歉说得这么不准确。我的问题仍然很模糊,因为我希望有人能告诉我如何在编译器中选择条件指令。(安娜·卡列尼娜的比喻很好)。我活该。:-)@RaymondChen它们都以相同的调用约定(即SYS V x64 ABI)为目标,但这并不重要。正如您所说,没有理由相信三个不同的编译器会给出相同的输出:)@PeterCordes。我的观点是,编译器之间的这些差异是由于一个相当特殊的情况造成的。像OP的问题那样,将其一般地外推到“三元运算符”似乎有些牵强;因此需要额外的说明。使用int作为返回类型,确实会生成“相同”的代码。我目前没有gcc bugzilla帐户,我对编译器的理解也是“零碎的”。你能把这个问题归档吗?我保证下次遇到可能的gcc错误时,我会亲自提交一个问题。@dannas:done。我认为gcc bugzilla帐户创建仍然是出于垃圾邮件原因关闭的,因此IDK如果你愿意的话也可以:/创建bugzilla帐户仍然是可能的,这个过程已经变成了手动的,你必须联系监督者。