📄 leq.asm
字号:
;解线性方程组的主元消去法(有回代过程)。
;入口条件:
; 方程组系数增广矩阵存放在片外RAM中指定的页面内,
; 数据格式为三字节二进制浮点数,方程组最大阶数为八阶。
;出口信息:
; 方程组的解X1,X2,...Xn依次在首址为WORK的内存中(二进制浮点数形式)。
ANNB EQU 20H ;方程组系数增广矩阵存放的片外RAM页面。
WORK EQU 30H ;工作区及方程根存放区首址。
WORK1 EQU 4BH ;辅助工作区。
N EQU 5 ;未知数个数(最多为八个)。
I DATA 29H ;行指针变量。
J DATA 2AH ;列指针变量。
K DATA 2BH ;辅助指针变量。
CON DATA 2CH ;计数器
TEMP EQU 2DH ;临时浮点变量存放首址。
FLAG DATA 23H ;浮点运算标志
PFA BIT FLAG.7
PFB BIT FLAG.6
PFC BIT FLAG.5
PFD BIT FLAG.4
ORG 0000H
LJMP TEST
ORG 100H
TEST: MOV DPTR,#DATS;把测试数据复制到片外RAM指定的页面。
MOV P2,#ANNB;系数增广矩阵存放首址。
MOV R1,#0
MOV A,#N ;计算系数个数。
MOV B,A
INC A
MUL AB
MOV CON,A
TRA0: MOV R5,#3 ;每个系数有三个字节。
MOV R0,#TEMP;先读到片内RAM。
TRA2: CLR A
MOVC A,@A+DPTR
MOV @R0,A
INC DPTR
INC R0
DJNZ R5,TRA2
MOV A,R1
PUSH ACC
MOV R0,#TEMP
PUSH DPH
PUSH DPL
LCALL BTOF ;把方程各系数由十进制浮点数转换成二进制浮点数。
POP DPL
POP DPH
POP ACC
MOV R1,A
MOV R5,#3 ;再存放到片外RAM指定页面。
TRA3: MOV A,@R0
MOVX @R1,A
INC R0
INC R1
DJNZ R5,TRA3
DJNZ CON,TRA0;将所有系数均存放好。
LCALL LEQ ;调用有回代主元消去法求解方程组的根。
MOV CON,#N ;将全部根
MOV R0,#WORK
TRA4: LCALL FTOB ;转换成十进制浮点数。
INC R0
INC R0
INC R0
DJNZ CON,TRA4
STOP: LJMP STOP
;测试结果X1=1.000 ( 01H 10H 00H )
;测试结果X2=-0.9999 ( 80H 99H 99H )(准确值为-1.000)
;测试结果X3=2.000 ( 01H 20H 00H )
;测试结果X4=-2.000 ( 81H 20H 00H )
;测试结果X5=1.000 ( 01H 10H 00H )
DATS: DB 01H,30H,0H ;系数增广矩阵A11=3.0
DB 01H,20H,0H ;A12=2.0
DB 41H,00H,0H ;A13=0.0
DB 01H,10H,0H ;A14=1.0
DB 81H,20H,0H ;A15=-2.0
DB 81H,30H,0H ;B1 =-3.0
DB 01H,10H,0H ;A21=1.0
DB 81H,10H,0H ;A22=-1.0
DB 01H,20H,0H ;A23=2.0
DB 01H,30H,0H ;A24=3.0
DB 01H,50H,0H ;A25=5.0
DB 01H,50H,0H ;B2 =5.0
DB 41H,00H,0H ;A31=0.0
DB 01H,30H,0H ;A32=3.0
DB 41H,00H,0H ;A33=0.0
DB 01H,20H,0H ;A34=2.0
DB 01H,10H,0H ;A35=1.0
DB 81H,60H,0H ;B3 =-6.0
DB 81H,10H,0H ;A41=-1.0
DB 41H,00H,0H ;A42=0.0
DB 01H,10H,0H ;A43=1.0
DB 01H,10H,0H ;A44=1.0
DB 41H,00H,0H ;A45=0.0
DB 81H,10H,0H ;B4 =-1.0
DB 01H,40H,0H ;A51=4.0
DB 01H,10H,0H ;A52=1.0
DB 01H,20H,0H ;A53=2.0
DB 81H,10H,0H ;A54=-1.0
DB 81H,10H,0H ;A55=-1.0
DB 01H,80H,0H ;B5 =8.0
LEQ: MOV DPH,#ANNB;无回代主元消去法。
MOV P2,#ANNB;指向系数存放页面。
MOV I,#0 ;从第一行(行号为0)开始处理。
LEQ0: MOV A,I ;取将要处理的行号。
INC A
XRL A,#N
JZ LEQ1 ;如果是最后一行,不必寻找主元。
LCALL FINDMIN ;寻找主元,并将其所在行交换到当前处理行位置上。
LEQ1: LCALL DIVMIN ;将当前处理行的各个系数除以主元,使主元为1。
MOV A,I
INC A
MOV K,A ;从主元下一行开始,进行消元处理。
XRL A,#N
JZ LEQ4 ;没有下一行,结束消元工作。
LEQ2: LCALL DEL ;进行消元处理。
INC K ;调整到下一行。
MOV A,K
XRL A,#N
JNZ LEQ2 ;直到各行均进行过消元处理。
INC I ;调整寻找主元的行号。
MOV A,I
XRL A,#N
JNZ LEQ0 ;直到整个系数矩阵主对角线全部为1。
LEQ4: MOV I,#0 ;增广矩阵的最后一列,就是方程组的常数项。
MOV J,#N
LCALL LOADH ;将其调入片内RAM中。
MOV I,#N-2 ;从倒数第二行开始进行回代。
LEQ5: MOV J,I
INC J
MOV A,#WORK1
LCALL LOADL ;将回代行主对角线右侧系数调入片内。
MOV A,#N ;计算乘积项数。
SETB C
SUBB A,I
PUSH ACC
MOV CON,A
MOV A,#N-1 ;计算Bn-1的地址。
MOV B,#3
MUL AB
ADD A,#WORK
MOV R1,A ;R1先指向Bn-1,即Xn-1的值。
MOV A,CON ;计算Ai,n-1的地址。
DEC A
MOV B,#3
MUL AB
ADD A,#WORK1
MOV R0,A ;R0先指向Ai,n-1。
LEQ6: LCALL FMUL ;计算乘积Ai,k×Bk→ Ai,k。
DEC R0 ;调整系数项指针。
DEC R0
DEC R0
DEC R1 ;调整根指针。
DEC R1
DEC R1
DJNZ CON,LEQ6;计算完各个乘积项。
POP CON
MOV A,R1
MOV R0,A ;指向Bi。
MOV R1,#WORK1;指向乘积项。
LEQ7: LCALL FSUB ;减去乘积项。
INC R1
INC R1
INC R1
DJNZ CON,LEQ7;减完各个乘积项后,便得到根Xi。
DEC I ;上移一行。
MOV A,I
JNB ACC.7,LEQ5;还有,继续回代。
RET ;求解方程组的任务完成。
FINDMIN:MOV J,I ;寻找主元,定位主对角线系数。
LCALL LOADH ;将主对角线系数及其以下同一列的系数读入片内。
MOV R0,#WORK;先设第一个系数为最大值。
MOV R1,#WORK+3;从第二个系数开始进行比较。
MOV A,#N ;计算比较的次数。
SETB C
SUBB A,I
MOV CON,A
MOV A,@R0 ;取绝对值。
CLR ACC.7
MOV @R0,A
MAX: MOV A,@R1 ;取绝对值。
CLR ACC.7
MOV @R1,A
LCALL FCMP ;比较。
JNC MAX1
MOV A,R1 ;以比较对象为新的最大值。
MOV R0,A
MAX1: INC R1 ;准备比较下一个系数。
INC R1
INC R1
DJNZ CON,MAX ;完成所有比较。
MOV A,R0 ;取最大值的地址。
CLR C
SUBB A,#WORK ;和主对角线系数的距离(字节数)。
JZ FINDE ;为零,主对角线系数就是最大值系数,不必交换。
MOV B,#3 ;将距离转换为系数个数。
DIV AB
ADD A,I ;加上当前行号,
MOV K,A ;得到最大值所在行号。
MOV J,I ;主对角线系数的列号和行号相同。
LCALL ADDR ;计算主对角线系数的地址。
MOV R0,DPL ;保存地址在R0中。
PUSH I ;保存主对角线系数的行号。
MOV I,K ;将行号改为最大值的行号(列号不变)。
LCALL ADDR ;计算地址。
MOV R1,DPL ;保存地址在R1中。
POP I ;恢复主对角线系数的行号。
MOV A,#N+1 ;计算待交换系数的字节数。
CLR C
SUBB A,J
MOV B,#3
MUL AB
MOV R7,A
XCHG: MOVX A,@R0 ;交换两行,使最大值系数处于主对角线上。
MOV R6,A
MOVX A,@R1
XCH A,R6
MOVX @R1,A
MOV A,R6
MOVX @R0,A
INC R1
INC R0
DJNZ R7,XCHG
FINDE: RET ;完成主元寻找和交换任务。
DEL: MOV J,I ;待消元的系数的列号等于主元的行号。
PUSH I ;保存主元的行号。
MOV I,K ;指向待消元的行号。
MOV A,#WORK ;指向片内工作区。
LCALL LOADL ;将待消元的一行系数调入片内工作区。
POP I ;恢复主元行号。
MOV A,#N ;计算需要调整数值的系数个数。
CLR C
SUBB A,J
MOV CON,A
MOV R0,#WORK+3;指向第一个待调整数值的系数A k , j。
MOV R1,#WORK1+3;指向主元数值行的第一个参照系数A i , j。
DEL1: MOV TEMP,WORK;将待消元的系数值A k , i复制到临时变量中。
MOV TEMP+1,WORK+1
MOV TEMP+2,WORK+2
MOV A,R0
PUSH ACC
MOV R0,#TEMP
LCALL FMUL ;计算A k , i×A i , j→TEMP。
POP ACC
MOV R0,A
MOV A,R1
PUSH ACC
MOV R1,#TEMP
LCALL FSUB ;计算A k , j=A k , j-A k , i×A i , j
POP ACC
MOV R1,A
INC R0
INC R0
INC R0
INC R1
INC R1
INC R1
DJNZ CON,DEL1;将待消元行有关系数全部调整好。
MOV J,I ;主元所在的列号等于行号。
INC J ;加一,得到已调整系数的最小列号。
PUSH I
MOV I,K ;取已调整系数的行号。
MOV A,#WORK+3;取已调整系数在片内的首址。
LCALL SAVE ;将全部已调整系数存回到片外RAM原来位置上。
POP I ;恢复主元行号。
RET ;一行消元处理结束。
DIVMIN: MOV J,I ;主元所在行系数处理。
MOV A,#WORK1;指向辅助工作区。
LCALL LOADL ;将主元所在行的系数调入片内RAM中。
MOV R1,#WORK1;以主元作除数。
MOV R0,#WORK1+3;其右的系数作为第一个被除数。
MOV A,#N ;计算需要处理的系数个数。
CLR C
SUBB A,I
MOV CON,A
DMIN: LCALL FDIV ;进行除法运算A i , j=A i , j/A i , i。
INC R0
INC R0
INC R0
DJNZ CON,DMIN
MOV A,#WORK1+3;指向片内第一个已经处理的系数。
MOV J,I
INC J ;列号j=i+1。
SAVE: MOV R0,A ;片内首址。
LCALL ADDR ;计算片外首址。
MOV A,#N+1 ;计算回存字节数。
CLR C
SUBB A,J
MOV B,#3
MUL AB
MOV R7,A
SAVE1: MOV A,@R0 ;回存到片外。
MOVX @DPTR,A
INC DPTR
INC R0
DJNZ R7,SAVE1
RET
LOADL: MOV R0,A ;片内首址。
LCALL ADDR ;计算片外首址。
MOV A,#N+1 ;计算回存字节数。
CLR C
SUBB A,J
MOV B,#3
MUL AB
MOV R7,A
LOAD1: MOVX A,@DPTR ;调入到片内。
MOV @R0,A
INC DPTR
INC R0
DJNZ R7,LOAD1
RET
LOADH: MOV R0,#WORK;将一列系数调入WORK为首址片内RAM中。
MOV A,#N ;计算同一列相邻系数中间间隔的字节数。
MOV B,#3
MUL AB
MOV R6,A
LCALL ADDR ;计算片外首址。
MOV A,#N ;计算调入系数个数。
CLR C
SUBB A,I
MOV R7,A
LOAD2: MOV R2,#3 ;每个系数为三个字节。
LOAD3: MOVX A,@DPTR ;调入一个系数。
MOV @R0,A
INC DPTR
INC R0
DJNZ R2,LOAD3
MOV A,DPL ;调整到同一列下一个相邻系数的首址。
ADD A,R6
MOV DPL,A
DJNZ R7,LOAD2;将所需系数全部调入片内RAM中。
RET
ADDR: MOV B,#N+1 ;计算A i , j的片外地址(低八位)。
MOV A,I
MUL AB
ADD A,J
MOV B,#3
MUL AB
MOV DPL,A
RET
;以下是浮点运算子程序库。
FADD: CLR F0
SJMP AS
FSUB: SETB F0
AS: LCALL MVR1
MOV C,F0
RRC A
XRL A,@R1
MOV C,ACC.7
ASN: MOV PFB,C
XRL A,@R0
RLC A
MOV F0,C
LCALL MVR0
LCALL AS1
MOV0: INC R0
INC R0
MOV A,R4
MOV @R0,A
DEC R0
MOV A,R3
MOV @R0,A
DEC R0
MOV A,R2
MOV C,PFA
MOV ACC.7,C
MOV @R0,A
CLR ACC.7
CLR OV
CJNE A,#3FH,MV01
SETB OV
MV01: MOV A,@R0
RET
MVR0: MOV A,@R0
MOV C,ACC.7
MOV PFA,C
MOV C,ACC.6
MOV ACC.7,C
MOV R2,A
INC R0
MOV A,@R0
MOV R3,A
INC R0
MOV A,@R0
MOV R4,A
DEC R0
DEC R0
RET
MVR1: MOV A,@R1
MOV C,ACC.7
MOV PFB,C
MOV C,ACC.6
MOV ACC.7,C
MOV R5,A
INC R1
MOV A,@R1
MOV R6,A
INC R1
MOV A,@R1
MOV R7,A
DEC R1
DEC R1
RET
AS1: MOV A,R6
ORL A,R7
JZ AS2
MOV A,R3
ORL A,R4
JNZ EQ1
MOV A,R6
MOV R3,A
MOV A,R7
MOV R4,A
MOV A,R5
MOV R2,A
MOV C,PFB
MOV PFA,C
AS2: RET
EQ1: MOV A,R2
XRL A,R5
JZ AS4
JB ACC.7,EQ3
MOV A,R2
CLR C
SUBB A,R5
JC EQ4
EQ2: CLR C
MOV A,R6
RRC A
MOV R6,A
MOV A,R7
RRC A
MOV R7,A
INC R5
ORL A,R6
JNZ EQ1
MOV A,R2
MOV R5,A
SJMP AS4
EQ3: MOV A,R2
JNB ACC.7,EQ2
EQ4: CLR C
LCALL RR1
ORL A,R3
JNZ EQ1
MOV A,R5
MOV R2,A
AS4: JB F0,AS5
MOV A,R4
ADD A,R7
MOV R4,A
MOV A,R3
ADDC A,R6
MOV R3,A
JNC AS2
LJMP RR1
AS5: CLR C
MOV A,R4
SUBB A,R7
MOV B,A
MOV A,R3
SUBB A,R6
JC AS6
MOV R4,B
MOV R3,A
LJMP RLN
AS6: CPL PFA
CLR C
MOV A,R7
SUBB A,R4
MOV R4,A
MOV A,R6
SUBB A,R3
MOV R3,A
RLN: MOV A,R3
ORL A,R4
JNZ RLN1
MOV R2,#0C1H
RET
RLN1: MOV A,R3
JB ACC.7,RLN2
CLR C
LCALL RL1
SJMP RLN
RLN2: CLR OV
RET
RL1: MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
DEC R2
CJNE R2,#0C0H,RL1E
CLR A
MOV R3,A
MOV R4,A
MOV R2,#0C1H
RL1E: CLR OV
RET
RR1: MOV A,R3
RRC A
MOV R3,A
MOV A,R4
RRC A
MOV R4,A
INC R2
CLR OV
CJNE R2,#40H,RR1E
MOV R2,#3FH
SETB OV
RR1E: RET
FMUL: LCALL MVR0
MOV A,@R0
XRL A,@R1
RLC A
MOV PFA,C
LCALL MUL0
LJMP MOV0
MUL0: LCALL MVR1
MUL1: MOV A,R3
ORL A,R4
JZ MUL6
MOV A,R6
ORL A,R7
JZ MUL5
MOV A,R7
MOV B,R4
MUL AB
MOV A,B
XCH A,R7
MOV B,R3
MUL AB
ADD A,R7
MOV R7,A
CLR A
ADDC A,B
XCH A,R4
MOV B,R6
MUL AB
ADD A,R7
MOV R7,A
MOV A,B
ADDC A,R4
MOV R4,A
CLR A
RLC A
XCH A,R3
MOV B,R6
MUL AB
ADD A,R4
MOV R4,A
MOV A,B
ADDC A,R3
MOV R3,A
JB ACC.7,MUL2
MOV A,R7
RLC A
MOV R7,A
LCALL RL1
MUL2: MOV A,R7
JNB ACC.7,MUL3
INC R4
MOV A,R4
JNZ MUL3
INC R3
MOV A,R3
JNZ MUL3
MOV R3,#80H
INC R2
MUL3: MOV A,R2
ADD A,R5
MD: MOV R2,A
JB ACC.7,MUL4
JNB ACC.6,MUL6
MOV R2,#3FH
SETB OV
RET
MUL4: JB ACC.6,MUL6
MUL5: CLR A
MOV R3,A
MOV R4,A
MOV R2,#41H
MUL6: CLR OV
RET
FDIV: INC R0
MOV A,@R0
INC R0
ORL A,@R0
DEC R0
DEC R0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -