?? leqn.asm
字號(hào):
;解線性方程組的主元消去法(無回代過程)。
;入口條件:
; 方程組系數(shù)增廣矩陣存放在片外RAM中指定的頁面內(nèi),
; 數(shù)據(jù)格式為三字節(jié)二進(jìn)制浮點(diǎn)數(shù),方程組最大階數(shù)為八階。
;出口信息:
; 方程組的解X1,X2,...Xn依次在首址為WORK的內(nèi)存中(二進(jìn)制浮點(diǎn)數(shù)形式)。
ANNB EQU 20H ;方程組系數(shù)增廣矩陣存放的片外RAM頁面。
WORK EQU 30H ;工作區(qū)及方程根存放區(qū)首址。
WORK1 EQU 4BH ;輔助工作區(qū)。
N EQU 5 ;未知數(shù)個(gè)數(shù)(最多八個(gè),以便存放在同一頁面內(nèi))。
I DATA 29H ;行指針變量。
J DATA 2AH ;列指針變量。
K DATA 2BH ;輔助指針變量。
CON DATA 2CH ;計(jì)數(shù)器。
TEMP EQU 2DH ;臨時(shí)浮點(diǎn)變量存放首址。
FLAG DATA 23H ;浮點(diǎn)運(yùn)算標(biāo)志
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;把測(cè)試數(shù)據(jù)復(fù)制到片外RAM指定的頁面。
MOV P2,#ANNB;系數(shù)增廣矩陣存放首址。
MOV R1,#0
MOV A,#N ;計(jì)算系數(shù)個(gè)數(shù)。
MOV B,A
INC A
MUL AB
MOV CON,A
TRA0: MOV R5,#3 ;每個(gè)系數(shù)有三個(gè)字節(jié)。
MOV R0,#TEMP;先讀到片內(nèi)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 ;把方程各系數(shù)由十進(jìn)制浮點(diǎn)數(shù)轉(zhuǎn)換成二進(jìn)制浮點(diǎn)數(shù)。
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;將所有系數(shù)均存放好。
LCALL LEQN ;調(diào)用無回代主元消去法求解方程組的根。
MOV CON,#N ;將全部根
MOV R0,#WORK
TRA4: LCALL FTOB ;轉(zhuǎn)換成十進(jìn)制浮點(diǎn)數(shù)。
INC R0
INC R0
INC R0
DJNZ CON,TRA4
STOP: LJMP STOP
;測(cè)試結(jié)果X1=1.000 ( 01H 10H 00H )
;測(cè)試結(jié)果X2=-0.9999 ( 80H 99H 99H )(準(zhǔn)確值為-1.000)
;測(cè)試結(jié)果X3=2.000 ( 01H 20H 00H )
;測(cè)試結(jié)果X4=-2.000 ( 81H 20H 00H )
;測(cè)試結(jié)果X5=1.000 ( 01H 10H 00H )
DATS: DB 01H,30H,0H ;系數(shù)增廣矩陣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
LEQN: MOV DPH,#ANNB;指向系數(shù)存放頁面。
MOV P2,#ANNB;指向系數(shù)存放頁面。
MOV I,#0 ;從第一行(行號(hào)為0)開始處理。
LEQ: MOV A,I ;取將要處理的行號(hào)。
INC A
XRL A,#N
JZ LEQ1 ;如果是最后一行,不必尋找主元。
LCALL FINDMIN ;尋找主元,并將其所在行交換到當(dāng)前處理行位置上。
LEQ1: LCALL DIVMIN ;將當(dāng)前處理行的各個(gè)系數(shù)除以主元,使主元為1。
MOV K,#0 ;從第一行開始,進(jìn)行消元處理。
LEQ2: MOV A,K ;取待消元行號(hào)。
XRL A,I
JZ LEQ3 ;如果是主元所在行號(hào),則跳過。
LCALL DEL ;進(jìn)行消元處理。
LEQ3: INC K ;調(diào)整到下一行。
MOV A,K
XRL A,#N
JNZ LEQ2 ;直到各行均進(jìn)行過消元處理。
INC I ;調(diào)整尋找主元的行號(hào)。
MOV A,I
XRL A,#N
JNZ LEQ ;直到整個(gè)系數(shù)矩陣成為單位矩陣。
MOV I,#0 ;增廣矩陣的最后一列,就是方程組的解。
MOV J,#N
LCALL LOADH ;將其調(diào)入片內(nèi)RAM中。
RET ;求解方程組的任務(wù)完成。
FINDMIN:MOV J,I ;尋找主元,定位主對(duì)角線系數(shù)。
LCALL LOADH ;將主對(duì)角線系數(shù)及其以下同一列的系數(shù)讀入片內(nèi)。
MOV R0,#WORK;先設(shè)第一個(gè)系數(shù)為最大值。
MOV R1,#WORK+3;從第二個(gè)系數(shù)開始進(jìn)行比較。
MOV A,#N ;計(jì)算比較的次數(shù)。
SETB C
SUBB A,I
MOV CON,A
MOV A,@R0 ;取絕對(duì)值。
CLR ACC.7
MOV @R0,A
MAX: MOV A,@R1 ;取絕對(duì)值。
CLR ACC.7
MOV @R1,A
LCALL FCMP ;比較。
JNC MAX1
MOV A,R1 ;以比較對(duì)象為新的最大值。
MOV R0,A
MAX1: INC R1 ;準(zhǔn)備比較下一個(gè)系數(shù)。
INC R1
INC R1
DJNZ CON,MAX ;完成所有比較。
MOV A,R0 ;取最大值的地址。
CLR C
SUBB A,#WORK ;和主對(duì)角線系數(shù)的距離(字節(jié)數(shù))。
JZ FINDE ;為零,主對(duì)角線系數(shù)就是最大值系數(shù),不必交換。
MOV B,#3 ;將距離轉(zhuǎn)換為系數(shù)個(gè)數(shù)。
DIV AB
ADD A,I ;加上當(dāng)前行號(hào),
MOV K,A ;得到最大值所在行號(hào)。
MOV J,I ;主對(duì)角線系數(shù)的列號(hào)和行號(hào)相同。
LCALL ADDR ;計(jì)算主對(duì)角線系數(shù)的地址。
MOV R0,DPL ;保存地址在R0中。
PUSH I ;保存主對(duì)角線系數(shù)的行號(hào)。
MOV I,K ;將行號(hào)改為最大值的行號(hào)(列號(hào)不變)。
LCALL ADDR ;計(jì)算地址。
MOV R1,DPL ;保存地址在R1中。
POP I ;恢復(fù)主對(duì)角線系數(shù)的行號(hào)。
MOV A,#N+1 ;計(jì)算待交換系數(shù)的字節(jié)數(shù)。
CLR C
SUBB A,J
MOV B,#3
MUL AB
MOV R7,A
XCHG: MOVX A,@R0 ;交換兩行,使最大值系數(shù)處于主對(duì)角線上。
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 ;完成主元尋找和交換任務(wù)。
DEL: MOV J,I ;待消元的系數(shù)的列號(hào)等于主元的行號(hào)。
PUSH I ;保存主元的行號(hào)。
MOV I,K ;指向待消元的行號(hào)。
MOV A,#WORK ;指向片內(nèi)工作區(qū)。
LCALL LOADL ;將待消元的一行系數(shù)調(diào)入片內(nèi)工作區(qū)。
POP I ;恢復(fù)主元行號(hào)。
MOV A,#N ;計(jì)算需要調(diào)整數(shù)值的系數(shù)個(gè)數(shù)。
CLR C
SUBB A,J
MOV CON,A
MOV R0,#WORK+3;指向第一個(gè)待調(diào)整數(shù)值的系數(shù)A k , j。
MOV R1,#WORK1+3;指向主元數(shù)值行的第一個(gè)參照系數(shù)A i , j。
DEL1: MOV TEMP,WORK;將待消元的系數(shù)值A(chǔ) k , i復(fù)制到臨時(shí)變量中。
MOV TEMP+1,WORK+1
MOV TEMP+2,WORK+2
MOV A,R0
PUSH ACC
MOV R0,#TEMP
LCALL FMUL ;計(jì)算A k , i×A i , j→TEMP。
POP ACC
MOV R0,A
MOV A,R1
PUSH ACC
MOV R1,#TEMP
LCALL FSUB ;計(jì)算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;將待消元行有關(guān)系數(shù)全部調(diào)整好。
MOV J,I ;主元所在的列號(hào)等于行號(hào)。
INC J ;加一,得到已調(diào)整系數(shù)的最小列號(hào)。
PUSH I
MOV I,K ;取已調(diào)整系數(shù)的行號(hào)。
MOV A,#WORK+3;取已調(diào)整系數(shù)在片內(nèi)的首址。
LCALL SAVE ;將全部已調(diào)整系數(shù)存回到片外RAM原來位置上。
POP I ;恢復(fù)主元行號(hào)。
RET ;一行消元處理結(jié)束。
DIVMIN: MOV J,I ;主元所在行系數(shù)處理。
MOV A,#WORK1;指向輔助工作區(qū)。
LCALL LOADL ;將主元所在行的系數(shù)調(diào)入片內(nèi)RAM中。
MOV R1,#WORK1;以主元作除數(shù)。
MOV R0,#WORK1+3;其右的系數(shù)作為第一個(gè)被除數(shù)。
MOV A,#N ;計(jì)算需要處理的系數(shù)個(gè)數(shù)。
CLR C
SUBB A,I
MOV CON,A
DMIN: LCALL FDIV ;進(jìn)行除法運(yùn)算A i , j=A i , j/A i , i。
INC R0
INC R0
INC R0
DJNZ CON,DMIN
MOV A,#WORK1+3;指向片內(nèi)第一個(gè)已經(jīng)處理的系數(shù)。
MOV J,I
INC J ;列號(hào)j=i+1。
SAVE: MOV R0,A ;片內(nèi)首址。
LCALL ADDR ;計(jì)算片外首址。
MOV A,#N+1 ;計(jì)算回存字節(jié)數(shù)。
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 ;片內(nèi)首址。
LCALL ADDR ;計(jì)算片外首址。
MOV A,#N+1 ;計(jì)算回存字節(jié)數(shù)。
CLR C
SUBB A,J
MOV B,#3
MUL AB
MOV R7,A
LOAD1: MOVX A,@DPTR ;調(diào)入到片內(nèi)。
MOV @R0,A
INC DPTR
INC R0
DJNZ R7,LOAD1
RET
LOADH: MOV R0,#WORK;將一列系數(shù)調(diào)入WORK為首址片內(nèi)RAM中。
MOV A,#N ;計(jì)算同一列相鄰系數(shù)中間間隔的字節(jié)數(shù)。
MOV B,#3
MUL AB
MOV R6,A
LCALL ADDR ;計(jì)算片外首址。
MOV A,#N ;計(jì)算調(diào)入系數(shù)個(gè)數(shù)。
CLR C
SUBB A,I
MOV R7,A
LOAD2: MOV R2,#3 ;每個(gè)系數(shù)為三個(gè)字節(jié)。
LOAD3: MOVX A,@DPTR ;調(diào)入一個(gè)系數(shù)。
MOV @R0,A
INC DPTR
INC R0
DJNZ R2,LOAD3
MOV A,DPL ;調(diào)整到同一列下一個(gè)相鄰系數(shù)的首址。
ADD A,R6
MOV DPL,A
DJNZ R7,LOAD2;將所需系數(shù)全部調(diào)入片內(nèi)RAM中。
RET
ADDR: MOV B,#N+1 ;計(jì)算A i , j的片外地址(低八位)。
MOV A,I
MUL AB
ADD A,J
MOV B,#3
MUL AB
MOV DPL,A
RET
;以下是浮點(diǎn)運(yùn)算子程序庫。
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
JNZ DIV1
MOV @R0,#41H
CLR OV
RET
DIV1: INC R1
MOV A,@R1
INC R1
ORL A,@R1
DEC R1
DEC R1
JNZ DIV2
SETB OV
RET
DIV2: LCALL MVR0
MOV A,@R0
XRL A,@R1
RLC A
MOV PFA,C
LCALL MVR1
LCALL DIV3
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -