Assembly X86汇编:为什么一个基本块有cmp和测试指令,这似乎是重复的工作

Assembly X86汇编:为什么一个基本块有cmp和测试指令,这似乎是重复的工作,assembly,x86,g++,Assembly,X86,G++,这是我的c函数: bool equalA = true; for (int i = 0; i < 4; i++) { if (str[i] != 'a') { equalA = false; } } if (equalA == true) { if(str.compare(4, 6, "matches")) { printf("%s", "matches\n")

这是我的c函数:

bool equalA = true;

for (int i = 0; i < 4; i++) {
    
    if (str[i] != 'a') {
        equalA = false; 
    }
}
if (equalA == true) {
    if(str.compare(4, 6, "matches")) {
        printf("%s", "matches\n");
    }
}
上面的代码用“a”检查str[i],如果不相等,movb将equalA设置为false。如果相等,则跳到.L5。然后继续循环

我的问题是: 不应该

  cmpb  $97, %al
  je .L5 
你会做同样的工作吗

如果str[i]=='a',将设置zflag,则je.L5将采用该分支。 如果str[i]!=“a”,则zflag将被清除。je.L5不会接受分支机构


为什么编译器会在cmpb指令后生成两行额外代码?

您是对的,它也应该这样做。我假设您没有在启用优化的情况下编译。很难解释为什么C编译器生成某些代码。顺便说一句,不同的编译器可能生成了不同的代码。尽管启用了优化,但另一个可能会生成此代码


然而,这是一种极端的过分简化,请参阅下面@PeterCordes的精彩评论,以了解有关程序优化的更多详细信息。

是的,没有优化。启用优化,很可能这些额外的行将消失。大多数C/C++编译器的代码生成器都会生成某种“模板代码”,这种代码有优化的空间,留给后一个优化阶段,这样可以更轻松地跨多个这样的“模板”处理此类冗余。@Tom:这是一种过于简化的描述,甚至不准确。像这样的优化大多发生在程序逻辑的内部表示上,通常是一种形式。对于GCC,它是GIMPLE(SSA),然后是RTL,用于寄存器分配和填充,最后生成asm。因此,它不像是将源代码转换为x86 asm模板,然后对其进行优化;当程序逻辑处于较少的特定于机器和寄存器分配细节的状态时,它会在生成asm之前进行优化。在没有优化的情况下,编译器会非常准确地解释代码:生成一个标志,然后测试该标志。这就是你写的,这就是发生的事情,因为优化关闭了。你告诉编译器不要优化,所以它没有。它碰巧选择将比较的
bool
结果具体化到一个寄存器中,然后对其进行测试。由于
-O0
@syacer please,它已经不得不将其存储到内存中;你问为什么《华盛顿邮报》投了反对票,有人试图给你反馈。不要把两者联系起来。投票在这个网站上是一种正常的行为,所以不要把它当作个人行为。@syaet:请阅读我们的,把处理行为留给我们的版主。
  cmpb  $97, %al
  je .L5