ATMEL AVR微控制器的开发方案
如果访问的字节数少(例如读取一个字符),使用这种寻址方式的效率高于指针方式。对于较大的区域,可能仍然是使用间接寻址比较有效(参见下面的示例)。
Loading of a character:
Indirect addressing (6 Bytes): Direct addressing (4 Bytes):
LDI R30,LOW(CHARVAR) LDS R16,CHARVAR
LDI R31,HIGH(CHARVAR)
LD R16, Z
Loading of a long integer:
Indirect addressing (12 Bytes) Direct addressing (16 Bytes)
LDI R30,LOW(LONGVAR) LDS R0,LONGVAR
LDI R31,HIGH(LONGVAR) LDS R1,LONGVAR+1
LDD R0,Z LDS R2,LONGVAR+2
LDD R1,Z+1 LDS R3,LONGVAR+3
LDD R2,Z+2
LDD R3,Z+3
零标志传播
为实现条件转移,需要使用一些指令来操作由一些标志(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
使用这种方式传播零标志,所有条件转移在最后一个减法操作完成后都会被执行,因为参与标志(溢出和正数标志)所剩部分只取决于最高位字节。
- SN2005学习系统 数字语音室解决方案(05-19)
- 以可编程DSP架构应对TD-SCDMA以及TD-LTE带来的设计挑战 (02-14)
- ARM-μCLinux嵌入式系统启动引导的实现(07-26)
- 多核处理器架构及调试方案(03-28)
- 基于DSP的电源解决方案(06-13)
- 间歇性Bug最佳解决方案(09-24)