📄 hm16.asm
字号:
;16比特汉明码测试程序(原始数据11字节,编码结果为16字节)
; [16,11,4] 增广汉明码校验矩阵: |
; D15 D14 D13 D12 D11 D10 D9 D7 D6 D5 D3 D16 D8 D4 D2 D1 校验码
; | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | C4=0FFFFH
; | 1 1 1 1 1 1 1 0 0 0 0 0 1 0 0 0 | C3=0FE08H
; | 1 1 1 1 0 0 0 1 1 1 0 0 0 1 0 0 | C2=0F1C4H
; | 1 1 0 0 1 1 0 1 1 0 1 0 0 0 1 0 | C1=0CDA2H
; | 1 0 1 0 1 0 1 1 0 1 1 0 0 0 0 1 | C0=0AB61H
SADD EQU 30H ;原始数据存放首址(11字节)
DADD EQU 40H ;编码结果存放首址(16字节)
RADD EQU 50H ;解码结果存放首址(11字节)
ERR BIT 00H ;出错标志。
ORG 0000H
LJMP MAIN
ORG 100H
MAIN: MOV R0,#SADD ;生成11个原始数据
MOV R2,#11
MOV A,#05H
S1: MOV @R0,A
ADD A,#11H
INC R0
DJNZ R2,S1
LCALL HAMBM ;进行编码
LCALL HAMJM ;进行解码,完全正确
MOV R0,#DADD
MOV A,@R0
XRL A,#20H ;制造一个差错
MOV @R0,A
LCALL HAMJM ;进行解码,完全正确
MOV R0,#DADD
MOV A,@R0
XRL A,#04H ;再制造一个差错
MOV @R0,A
LCALL HAMJM ;进行解码,不能正确恢复
STOP: LJMP STOP ;
;编码算法
HAMBM: MOV R1,#DADD
MOV R0,#SADD+8 ;后3个字节用来拆分
MOV A,@R0
MOV R5,A
INC R0
MOV A,@R0
MOV R6,A
INC R0
MOV A,@R0
MOV R7,A
MOV R0,#SADD
HAMBM3: MOV A,@R0 ;取前8个字节中的一个字节(8比特)
MOV R3,A
MOV A,R7 ;从后3个字节中各移出1比特(共3比特)
RLC A
MOV R7,A
RRC A
MOV R4,A
MOV A,R6
RLC A
MOV R6,A
MOV A,R4
RRC A
MOV R4,A
MOV A,R5
RLC A
MOV R5,A
MOV A,R4
RRC A
ANL A,#0E0H
MOV R4,A ;得到11比特信息位(R3和R4的高3位)。
ANL A,#61H ;求校验位D1
MOV C,P
MOV A,R3
ANL A,#0ABH
JNB P,HAMBM4
CPL C
HAMBM4: MOV A,R4
MOV ACC.0,C
MOV R4,A ;拼装进低字节
ANL A,#0A2H ;求校验位D2
MOV C,P
MOV A,R3
ANL A,#0CDH
JNB P,HAMBM5
CPL C
HAMBM5: MOV A,R4
MOV ACC.1,C
MOV R4,A ;拼装进低字节
ANL A,#0C4H ;求校验位D4
MOV C,P
MOV A,R3
ANL A,#0F1H
JNB P,HAMBM6
CPL C
HAMBM6: MOV A,R4
MOV ACC.2,C
MOV R4,A ;拼装进低字节
ANL A,#08H ;求校验位D8
MOV C,P
MOV A,R3
ANL A,#0FEH
JNB P,HAMBM7
CPL C
HAMBM7: MOV A,R4
MOV ACC.3,C
MOV R4,A ;拼装进低字节
MOV C,P ;求校验位D16
MOV A,R3
JNB P,HAMBM8
CPL C
HAMBM8: MOV A,R4
MOV ACC.4,C
MOV R4,A ;拼装进低字节
MOV A,R3 ;输出两字节编码结果(R3R4)
MOV @R1,A
INC R1
MOV A,R4
MOV @R1,A
INC R1
INC R0
CJNE R0,#SADD+8,HAMBM3;共输出16字节编码结果
RET
;解码算法:
HAMJM: CLR ERR ;出错标志初始化。
MOV R1,#RADD
MOV R0,#DADD
MOV R2,#8 ;将16字节编码分为8组进行解码
HAMJM2: MOV A,@R0 ;每组2字节,装入R3R4中
MOV R3,A
MOV C,P
INC R0
MOV A,@R0
MOV R4,A
INC R0
JNB P,HAMJM3
CPL C
HAMJM3: MOV F0,C ;将16比特的校验结果装入F0中。
MOV B,#0 ;初始化校验码
MOV A,R4 ;D1校验
ANL A,#61H
MOV C,P
MOV A,R3
ANL A,#0ABH
JNB P,HAMJM4
CPL C
HAMJM4: MOV B.0,C ;拼装D1
MOV A,R4 ;D2校验
ANL A,#0A2H
MOV C,P
MOV A,R3
ANL A,#0CDH
JNB P,HAMJM5
CPL C
HAMJM5: MOV B.1,C ;拼装D2
MOV A,R4 ;D4校验
ANL A,#0C4H
MOV C,P
MOV A,R3
ANL A,#0F1H
JNB P,HAMJM6
CPL C
HAMJM6: MOV B.2,C ;拼装D4
MOV A,R4 ;D8校验
ANL A,#08H
MOV C,P
MOV A,R3
ANL A,#0FEH
JNB P,HAMJM7
CPL C
HAMJM7: MOV B.3,C ;拼装D8
MOV A,B ;取三个校验结果。
JZ HAMJMC ;汉明码无差错,信息有效。
JB F0,HAMJM8 ;差错判断。
SETB ERR ;发现两个差错,设立出错标志。
HAMJM8: INC A
MOVC A,@A+PC ;一个差错,查表得到纠错位置码。
SJMP HAMJM9
DB 01H,02H,20H,04H
DB 40H,80H,01H,08H
DB 02H,04H,08H,10H
DB 20H,40H,80H
HAMJM9: XCH A,B
INC A
MOVC A,@A+PC ;字节码(0:低字节,1:高字节)
SJMP HAMJMA
DB 0,0,0,0,0,0,1,0
DB 1,1,1,1,1,1,1,0
HAMJMA: JNZ HAMJMB
MOV A,B
XRL A,R4 ;低字节纠错处理。
MOV R4,A ;保存纠错后的汉明码。
SJMP HAMJMC
HAMJMB: MOV A,B
XRL A,R3 ;高字节纠错处理。
MOV R3,A ;保存纠错后的汉明码。
HAMJMC: MOV A,R3 ;纠错后,高字节全部为信息位
MOV @R1,A ;输出解码结果
INC R1
MOV A,R4 ;低字节只有3比特信息,将其分别拼装保存
RLC A
MOV R4,A
MOV A,R5
RLC A
MOV R5,A
MOV A,R4
RLC A
MOV R4,A
MOV A,R6
RLC A
MOV R6,A
MOV A,R4
RLC A
MOV R4,A
MOV A,R7
RLC A
MOV R7,A
DEC R2
MOV A,R2
JZ HAMJMD ;低字节只有3比特信息,将其分别拼装保存
LJMP HAMJM2
HAMJMD: MOV A,R5 ;将拼装出来的三个字节信息输出。
MOV @R1,A
INC R1
MOV A,R6
MOV @R1,A
INC R1
MOV A,R7
MOV @R1,A
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -