Example ; Multiply two Q15 numbers (VarA and VarB) and store result in
; VarC as a Q15 number:
MOV T,@VarA ; T = VarA (Q15)
MPY ACC,T,@VarB ; ACC = VarA * VarB (Q30)
MOVH @VarC,ACC << 1 ; VarC = ACC >> (16−1) (Q15)
; VarC as a Q31 number:
MOV T,@VarA ; T = VarA (T = Q14)
MPY ACC,T,@VarB ; ACC = VarA * VarB (ACC = Q28)
MOV @VarC+0,ACC << 3 ; VarC low = ACC << 3
MOVH @VarC+1,ACC << 3 ; VarC high = ACC >> (16−1) (VarC = Q31)
上面的移位是根据什么的呢?分号后面的注释有错吗?这是手册上面的例子得来的,最后一句的解析怎么和MOVH @VarC,ACC << 1 ; VarC = ACC >> (16−1) (Q15)不同呢?移位的数也不同
Hardy Zhou:
; VarC as a Q15 number:
MOV T,@VarA ; T = VarA (Q15)MPY ACC,T,@VarB ; ACC = VarA * VarB (Q30)MOVH @VarC,ACC << 1 ; VarC = ACC >> (16−1) (Q15)
MOVH是取高16bit,而ACC本来是32bit的Q30格式,如果不对ACC左移1位,那么舍弃低16位,VarC会变成Q14格式, 所以需要左移一位,
所以实际上等效于 ACC右移15bit, 也就是 Varc = ACC>> (16-1)
; VarC as a Q31 number:MOV T,@VarA ; T = VarA (T = Q14)MPY ACC,T,@VarB ; ACC = VarA * VarB (ACC = Q28)MOV @VarC+0,ACC << 3 ; VarC low = ACC << 3MOVH @VarC+1,ACC << 3 ; VarC high = ACC >> (16−1) (VarC = Q31)
最后一句的意思是: ACC是Q28的格式,所以需要将ACC左移动3位,变成Q31格式,然后分别赋值给VarC的高16位和低16位
VarC high = (ACC<<3)>>16 = ACC>>13 实际上就是右移了13bit
所以注解应该是错的
如果VarA和VarB都是Q15格式
那么 VarC high = (ACC<<1)>>16 = ACC>>15,那就是跟注解一样,但是VarA和VarB换成Q14的格式,结果就有差别