微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > MCU和DSP > 与编译器开发商密切合作优化微控制器开发

与编译器开发商密切合作优化微控制器开发

时间:06-13 来源:互联网 点击:
零标志传播

为实现条件转移,需要使用一些指令来操作由一些标志(flag)构成的AVR状态寄存器。跟在这类指令之后的条件转移指令(conditional branch instruction)是否执行转移,取决于这些标志的设置。使用运算指令操作这些标志,就可检查一个数A与另一个数B之间的大小关系。当被检查的数为 8位的数时,不存在什么问题,因为所有标志都依赖一条指令设置的标志值。当被检查的数为16位或32位的数时(这在C语言中是常有的情况),问题就有点棘手了,例如一个32位减法操作就相当于要连续进行4个8位减法操作,而每做一次8位减法,就会产生一组新的标志。

为传播进位标志,大多数处理器都包含一些能处理进位标志先前设置值的指令。例如,带进位的减法(SBC)指令;执行SBC A,B语句就相当于将A变成进位位。但要正确完成所有的条件转移操作,这里还有另一个标志需要传播,即零标志。

示例:

   A=R3:R2:R1:R0,  
   B=R7:R6:R5:R4

我们打算从A中减去B,并如果A=B就跳转到一个指定位置。如果这个零标志只依赖于最后的运算指令,那么下面的指令将不会执行:

   SUB R0,R4
   SBC R1,R5
   SBC R2,R6
   SBC R3,R7  ; R3=R7
   => Zero flag set
   BREQ destination

这是因为BREQ指令使用的标志值只取决于最后的SBC指令设置的标志值。如果大多数高位直接相等,即便32位数不相等,零标志也将被置位,而转移也会被执行。这种问题也会出现在其他的条件转移上。

有两种办法可以解决这个问题。一是保存每个指令产生的标志,然后在第四个减法完成后检查所有的零标志。另一个更精细的方法是在进位指令中传播零标志(参见下面方式):

Znew =Not(R7) AND
   Not(R6) AND
   ...
   Not(R0) AND
   Zold

使用这种方式传播零标志,所有条件转移在最后一个减法操作完成后都会被执行,因为参与标志(溢出和正数标志)所剩部分只取决于最高位字节。

作者:爱特梅尔公司 Gaute Myklebust

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top