使用Arduino,我必须在Atmel AVR Assembly中为我的计算机科学类编写一个函数,用于计算汇编中两个8位值的8位平均值。我也不被允许使用任何分支指令(但跳过很好)。
这是我到目前为止所做的:
.global average
average:
add r24, r22
asr r24
ret
对于我必须计算69和60的平均值的程序部分,它返回-64而不是64.有谁知道如何使这个功能起作用?任何帮助将不胜感激。
答案 0 :(得分:10)
诀窍是添加然后rotate-with-carry将9位结果除以2并将8位结果留在寄存器中。
我在评论中链接的问题的两个答案使用:first,second。
AVR的实现是:
add r24, r25 ; 9-bit result in C and r24
ror r24 ; rotate-through-carry, like x86's RCR instruction
这适用于有符号的有符号或无符号解释,因为我们所做的只是从加法的9位完整结果中丢弃低位。没有算术与逻辑移位选择,也没有回绕。
还要注意通过向-infinity移动舍入来划分(不像C&C的整数除法运算符那样截断为零)。因此(1 + -2) >> 1
为-1
。
这个小到足以让你把它放在一个宏中,而不是一个函数。在大多数呼叫站点上可能至少需要2条指令,因此即使您可以使用单字RCALL instruction而不是2字CALL,内联也会保存代码大小。