当前位置: 首页 > 知识库问答 >
问题:

X86程序集:为什么一个基本块有cmp和测试指令,似乎是重复的工作[重复]

臧增
2023-03-14

下面是我的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");
    }
}
movzbl  (%rax), %eax
cmpb    $97, %al
setne   %al
testb   %al, %al
je  .L5
movb    $0, -981(%rbp)
.L5:
addl    $1, -980(%rbp)
jmp .L6
  cmpb  $97, %al
  je .L5 

如果str[i]=='a',则将设置zflag,je.L5将接受分支。如果str[i]!='a',则将清除zflag。je.L5不会拿树枝。

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

共有1个答案

詹钊
2023-03-14

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

然而,这是一个极端的过分简化,请参阅下面@PeterCordes的优秀评论,以获得更多关于程序优化的细节。

 类似资料:
  • 我在学组装。我拆解了一个简单的C程序,并用GDB进行了调试。但我注意到的一件事是,值的移动非常频繁。 RDI的值在rbp-0x18(<+8>)处移动到堆栈,RSI的值在rbp-0x20(+12)处移动到堆栈。然后,rbp-0x18处的值被移动到rax(+16),该值将再次被移动到rdi(+20)。为什么要这样做?为什么不直接使用rdi,或者至少通过rax(<+16>)直接将rbp-0x18移动到r

  • gameStart是一个全局变量,初始值为false。通常,当我点击左、右、上或下按钮时,gameStart变量设置为true,但if(gameStart)不起作用。但是当我用注释的块减慢速度时,if(gameStart)运行正常。为什么会发生这种情况?

  • 我读过,x86的INC指令不是原子指令。我的问题是为什么会这样?假设我们在x86-64上递增一个64位整数,我们可以用一条指令来递增,因为INC指令同时处理内存变量和寄存器。那么为什么它不是原子的呢?

  • 问题内容: 这个问题已经在这里有了答案 : 在排序时访问列表 (2个答案) 6年前关闭。 我想就地对列表进行排序,并尝试在排序过程中(功能内)使用列表本身。我发现列表本身似乎是空的。 所以我尝试了: 并得到 有什么解释吗? 问题答案: 从源代码: 并从Mutable Sequence Types文档中 : CPython实现细节 :在对列表进行排序时,尝试使列表变异甚至检查的效果是不确定的。Pyt

  • 我有以下代码来比较数字并增加一个变量,如果真或假 我有8个这样的检查。我想知道,如果我创建了一个包含ret的单Failinc和passinc子程序,我如何在cmp之后调用它?

  • 因此,正如一个人在之前的帖子中所说的,我会使用: 包括行末的“我的文件”。 由于未使用,我想我应该在标准输出中接收操作的结果。然后执行它并获得(注意,我使用而不是只是为了查看是否可以根据需要修改文件,因为在本例中,文件已经有了所需的行): 所以如您所见,文件没有更改。我做错了什么? 感谢阅读