为什么Gcc以错误的方式编译代码?

时间:2014-04-14 06:49:29

标签: c gcc compilation avr

我试图找到我的AVR ATtiny861A(8位)程序无法正常工作的原因。现在我刚开始使用Atmel Studio(之前我使用的是CodeVision AVR)。

注释中包含初始C代码的汇编程序代码如下:

        if(data & 0x8000)
  84:   33 23           and r19, r19
  86:   14 f4           brge    .+4         ; 0x8c <WriteDAC+0x2e>

我无法理解这段代码是如何正常工作的。

Codevision正确编译:

; 0000 00EE     (data&0x8000) ? (DAC_DIN=1) : (DAC_DIN=0);
    SBRS R17,7
    RJMP _0x10

我只发布了我无法理解的部分代码。

2 个答案:

答案 0 :(得分:4)

AND指令根据结果设置条件代码,该结果与输入的值相同。由于您正在测试最顶部的位,结果是负数,因此条件分支可以简单地使用“更大或相等”条件测试此标志,并将其用于条件分支,该分支对应于if语句。 / p>

要求codevision编译器生成一个0或1的变量,具体取决于最顶层的位(因此您有不同的源代码:一个是if语句,另一个是三元表达式),这是通过将位向下移动并用零填充寄存器来完成的,它通过使用不同类型的条件跳转来完成。

两者都完全正确。

答案 1 :(得分:2)

BRGE指令执行Branch if Greater or Equal Signed

由于使用and执行0x8000操作等于测试16位操作数中的符号位,因此它将设置符号位并执行分支。


SBRS执行Skip if Bit in Register is Set

使用and执行0x8000操作等于测试16位操作数的高字节中的第7位。


可以管理这些指令以执行相同的结果,因此我假设每个编译器都是按照您发布的代码的方式自行完成的。

如果他们的行为有所不同,请发布更多信息并让我们慎重。

参考文献:

http://www.atmel.no/webdoc/avrassembler/avrassembler.wb_BRGE.html

http://www.atmel.no/webdoc/avrassembler/avrassembler.wb_SBRS.html