在 PIC16(或类似)上加进
Adding with carry on PIC16 (or similar)
PIC 16 上没有 "add with carry" 指令。但是如果我必须添加比一个字节更大的数据量怎么办?我发现的所有 Web 资源和 Microchip 应用笔记都建议如下:
MOVF LSB_A, w
ADDWF LSB_B
MOVF MSB_A, w
BTFSC STATUS, C
INCFSZ MSB_A, w
ADDWF MSB_B
但上面的代码将不起作用。我的意思是 16 位结果是正确的,但是进位设置不正确,所以你不能通过重复上面代码的第二部分来扩展计算范围。到目前为止我说得对吗?
下面是我的进位加法实现:
MOVF BYTE1, w
BTFSC STATUS, C
ADDLW 1
RLF TEMP ; save the carry
ADDWF BYTE2
BTFSS STATUS, C
RRF TEMP ; restore the carry (from the first addition)
您可以对最低有效字节使用普通加法,或者在使用带进位的加法序列之前清除进位。
我想它是可行的,但是对于这个问题有更有效的解决方案吗?
Microchip 的代码模块库 (CML) 给出了以下用于 16 位加法的代码片段,它似乎可以解决您描述的溢出情况(对于评论来说太大了,所以我希望您能原谅我作为答案):
; Snippet: 16-bit A+B
;
; Inputs: A_high, A_low, B_high, B_low
; Outputs: RES_high, RES_low
movf A_low, W
addwf B_low, W
movwf RES_low ; Result in RES_low
movlw 0x00 ; Clear W
btfsc STATUS, C
movlw 0x01 ; C=1, carry present. Set W to add 1 to high bytes.
; C=0, there was no carry from low byte to high byte
addwf A_high, W ; Add A_high to W (either 0, or 1 if carry)
btfsc STATUS, C ; Check for o/f when adding low carry
goto early_overflow ; if don't check here, A_high = 0xFF will miss high byte carry
addwf B_high, W ; Add B_high to above
movwf RES_high ; Result in RES_high
btfss STATUS, C ; Check whole 16-bit addition for carry
goto end_add16 ; C=0, result valid
goto overflow ; C=1, result overflowed
early_overflow:
addwf B_high, W ; Add B_high to A_high + carry
movwf RES_high ; Result in RES_high
overflow:
; Can place code here to handle
; what to do in case result overflowed.
end_add16: ; end of snippet
PIC 16 上没有 "add with carry" 指令。但是如果我必须添加比一个字节更大的数据量怎么办?我发现的所有 Web 资源和 Microchip 应用笔记都建议如下:
MOVF LSB_A, w
ADDWF LSB_B
MOVF MSB_A, w
BTFSC STATUS, C
INCFSZ MSB_A, w
ADDWF MSB_B
但上面的代码将不起作用。我的意思是 16 位结果是正确的,但是进位设置不正确,所以你不能通过重复上面代码的第二部分来扩展计算范围。到目前为止我说得对吗?
下面是我的进位加法实现:
MOVF BYTE1, w
BTFSC STATUS, C
ADDLW 1
RLF TEMP ; save the carry
ADDWF BYTE2
BTFSS STATUS, C
RRF TEMP ; restore the carry (from the first addition)
您可以对最低有效字节使用普通加法,或者在使用带进位的加法序列之前清除进位。 我想它是可行的,但是对于这个问题有更有效的解决方案吗?
Microchip 的代码模块库 (CML) 给出了以下用于 16 位加法的代码片段,它似乎可以解决您描述的溢出情况(对于评论来说太大了,所以我希望您能原谅我作为答案):
; Snippet: 16-bit A+B
;
; Inputs: A_high, A_low, B_high, B_low
; Outputs: RES_high, RES_low
movf A_low, W
addwf B_low, W
movwf RES_low ; Result in RES_low
movlw 0x00 ; Clear W
btfsc STATUS, C
movlw 0x01 ; C=1, carry present. Set W to add 1 to high bytes.
; C=0, there was no carry from low byte to high byte
addwf A_high, W ; Add A_high to W (either 0, or 1 if carry)
btfsc STATUS, C ; Check for o/f when adding low carry
goto early_overflow ; if don't check here, A_high = 0xFF will miss high byte carry
addwf B_high, W ; Add B_high to above
movwf RES_high ; Result in RES_high
btfss STATUS, C ; Check whole 16-bit addition for carry
goto end_add16 ; C=0, result valid
goto overflow ; C=1, result overflowed
early_overflow:
addwf B_high, W ; Add B_high to A_high + carry
movwf RES_high ; Result in RES_high
overflow:
; Can place code here to handle
; what to do in case result overflowed.
end_add16: ; end of snippet