找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11710|回复: 3
收起左侧

51单片机挺好用的汇编子程序汇总,有用拿走

[复制链接]
ID:275310 发表于 2018-1-12 18:07 | 显示全部楼层 |阅读模式
51挺好用的子程序汇总,有用拿走!

所有资料51hei提供下载:
MSC51PRO.rar (19.76 KB, 下载次数: 120)


单片机汇编语言源程序如下:
  1. ;MCS-51单片机实用子程序库
  2. ;片内RAM初始化子程序
  3. IBCLR:         MOV A,R0
  4.          MOV R1,A
  5.          CLR A
  6. IBC1:         MOV @R1,A
  7.          INC R1
  8.          DJNZ R7,IBC1
  9.          RET
  10. ;片外RAM初始化子程序
  11. EBCLR1: MOV A,ADDPL
  12.          MOV DPL,A
  13.          MOV A,ADDPH
  14.          MOV DPH,A
  15.          CLR C
  16. EBC11:         MOVX @DPTR,A
  17.          INC DPTR
  18.          DJNZ R7,EBC11
  19.          RET
  20. ;片外RAM初始化子程序(双字节个单元)
  21. EBCLR2: MOV A,ADDPL
  22.          MOV DPL,A
  23.          MOV A,ADDPH
  24.          MOV DPH,A
  25.          MOV A,R7
  26.          JZ EBC21
  27.          INC R6
  28. EBC21:         CLR A
  29.          MOVX @DPTR,A
  30.          INC DPTR
  31.          DJNZ R7,EBC21
  32.          DJNZ R6,EBC21
  33.          RET
  34. ;内部RAM数据复制程序
  35. ;入口: R0,R7
  36. ;占用资源: A
  37. ;堆栈需求: 2字节
  38. ;出口: R1
  39. IBMOV:         MOV A,R0
  40.          ADD A,R7
  41.          MOV R0,A
  42.          MOV A,R1
  43.          ADD A,R7
  44.          MOV R1,A
  45. IBM1:         DEC R0
  46.          DEC R1
  47.          MOV A,@R0
  48.          MOV @R1,A
  49.          DJNZ R7,IBM1
  50.          RET
  51. ;外部RAM数据复制程序
  52. ;入口: ADDPH,ADDPL,R7
  53. ;占用资源: ACC
  54. ;堆栈需求: 2字节
  55. ;出口: R0,R1
  56. EBMOV1: MOV A,ADDPL
  57.          ADD A,R7
  58.          MOV DPL,A
  59.          CLR A
  60.          ADDC A,ADDPH
  61.          MOV DPH,A
  62.          MOV A,R7
  63.          ADD A,R1
  64.          XCH A,R0
  65.          ADDC A,#00H
  66.          MOV P2,A
  67. EBM11:         DEC R0
  68.          CJNE R0,#0FFH,EBM12
  69.          DEC P2
  70. EBM12:         DEC DPL
  71.          MOV A,DPL
  72.          CJNE A,#0FFH,EBM13
  73.          DEC DPH
  74. EBM13:         MOVX A,@R0
  75.          MOVX @DPTR,A
  76.          DJNZ R7,EBM11
  77.          RET
  78. ;外部RAM数据复制程序
  79. ;入口: ADDPH,ADDPL,R6,R7
  80. ;占用资源: ACC
  81. ;堆栈需求: 2字节
  82. ;出口: R0,R1
  83. EBMOV2: MOV A,ADDPL
  84.          ADD A,R7
  85.          MOV DPL,A
  86.          MOV A,R6
  87.          ADDC A,ADDPH
  88.          MOV DPH,A
  89.          MOV A,R7
  90.          ADD A,R1
  91.          XCH A,R0
  92.          ADDC A,R6
  93.          MOV P2,A
  94.          MOV A,R7
  95.          JZ EBM21
  96.          INC R6
  97. EBM21:         DEC R0
  98.          CJNE R0,#0FFH,EBM22
  99.          DEC P2
  100. EBM22:         DEC DPL
  101.          MOV A,DPL
  102.          CJNE A,#0FFH,EBM23
  103.          DEC DPH
  104. EBM23:         MOVX A,@R0
  105.          MOVX @DPTR,A
  106.          DJNZ R7,EBM21
  107.          DJNZ R6,EBM21
  108.          RET
  109. ;外部RAM数据复制到内部RAM程序
  110. ;入口: ADDPH,ADDPL,R7
  111. ;占用资源: ACC
  112. ;堆栈需求: 2字节
  113. ;出口: R0
  114. ITEMOV: MOV A,ADDPL
  115.          ADD A,R7
  116.          MOV DPL,A
  117.          MOV A,ADDPH
  118.          ADDC A,#00H
  119.          MOV DPH,A
  120.          MOV A,R0
  121.          ADD A,R7
  122.          MOV R0,A
  123. ITEM1:         DEC R0
  124.          DEC DPL
  125.          MOV A,DPL
  126.          CJNE A,#0FFH,ITEM2
  127.         DEC DPH
  128. ITEM2:         MOVX A,@DPTR
  129.          MOV @R0,A
  130.          DJNZ R7,ITEM1
  131.          RET
  132. ;限幅滤波程序
  133. ;入口: A,SDAT,DELTY
  134. ;占用资源: B
  135. ;堆栈需求: 2字节
  136. ;出口: A
  137. JUGFILT:MOV B,A
  138.          CLR C
  139.          SUBB A,SDAT
  140.          JNC JUGFT1
  141.          CPL A
  142.          INC A
  143. JUGFT1: SETB A
  144.          SUBB A,#DELTY
  145.          JNC JUGFT3
  146.          MOV A,SDAT
  147.          RET
  148. JUGFT3: MOV A,B
  149.          MOV SDAT,A
  150.          RET
  151. ;中位值滤波程序
  152. ;入口: ADDPH,ADDPL,N
  153. ;占用资源: ESELSORT
  154. ;堆栈需求: 4字节
  155. ;出口: A
  156. MEDFILT:LCALL ESELSORT
  157.          MOV A,N
  158.          CLR C
  159.          RRC A
  160.          ADD A,ADDPL
  161.          MOV DPL,A
  162.          MOV A,ADDPH
  163.          MOV DPH,A
  164.          JNC MEDFT1
  165.          INC DPH
  166. MEDFT1: MOVX A,@DPTR
  167.          RET
  168. ;N点算术平均滤波
  169. ;入口: ADDPH,ADDPL,N
  170. ;占用资源: B,R3,R4
  171. ;堆栈需求: 2字节
  172. ;出口: A
  173. AVFILT: MOV A,ADDPL
  174.          MOV DPL,A
  175.          MOV A,ADDPH
  176.          MOV DPH,A
  177.          CLR A
  178.          MOV R3,A
  179.          MOV R4,A
  180.          MOV R7,N
  181. AVFT1:         MOVX A,@DPTR
  182.          INC DPTR
  183.          ADD A,R4
  184.          MOV R4,A
  185.          JNC AVFT2
  186.          INC R3
  187. AVFT2:         DJNZ R7,AVFT1
  188.          MOV R7,N
  189.          MOV R2,#00H
  190.          LCALL NDIV31
  191.          MOV A,R4
  192.          RET
  193. ;N点加权平均滤波
  194. ;入口: ADDPH,ADDPL,N
  195. ;占用资源: B,R3,R4
  196. ;堆栈需求: 2字节
  197. ;出口: A
  198. QAVFILT:CLR A
  199.          MOV R3,A
  200.          MOV R4,A
  201.          MOV R7,N
  202.          MOV P2,ADDPH
  203.          MOV R1,ADDPL
  204.          MOV DPTR,#QAVTAB
  205. QAVFT1: MOVC A,@A+DPTR
  206.          MOV B,A
  207.          MOVX A,@R1
  208.          INC DPTR
  209.          INC R1
  210.          MUL AB
  211.          ADD A,R4
  212.          MOV R4,A
  213.         MOV A,B
  214.          ADDC A,R3
  215.          MOV R3,A
  216.          DJNZ R7,QAVFT1
  217.          MOV A,R4
  218.          JNB ACC.7,QAVFT2
  219.          INC R3
  220. QAVFT2: MOV A,R3
  221.          RET
  222. QAVTAB: DB
  223. ;一阶加权滞后滤波程序
  224. ;入口: A,DELTY
  225. ;占用资源: B,R3,R4
  226. ;堆栈需求: 2字节
  227. ;出口: A
  228. BQFILT: MOV B,A
  229.          CLR A
  230.          MOV DPTR,#ABTAB
  231.          MOVC A,@A+DPTR
  232.          MUL AB
  233.          MOV R4,A
  234.          MOV R3,B
  235.          MOV A,#01H
  236.          MOVC A,@A+DPTR
  237.          MOV B,DELTY
  238.          MUL AB
  239.          ADD A,R4
  240.          MOV R4,A
  241.          MOV A,B
  242.          ADDC A,R3
  243.          MOV R3,A
  244.          MOV A,R4
  245.          JNB ACC.7,FT1
  246.          INC R3
  247. FT1:         MOV A,R3
  248.          MOV DELTY,A
  249.          RET
  250. BQTAB:         DB 80H,80H
  251. ;双字节取补程序 /(R3R4)=(R3R4)
  252. ;入口: R3,R4
  253. ;占用资源: ACC
  254. ;堆栈需求: 2字节
  255. ;出口: R3,R4
  256. CMPT:         MOV A,R4
  257.          CPL A
  258.          ADD A,#01H
  259.          MOV R4,A
  260.          MOV A,R3
  261.          CPL A
  262.          ADDC A,#00H
  263.          MOV R3,A
  264.          RET
  265. ;N节取补程序 /([R0])=([R0])
  266. ;入口: R0,R7
  267. ;占用资源: ACC,B
  268. ;堆栈需求: 2字节
  269. ;出口: R0
  270. NCMPTN: MOV B,R0
  271.          SETB C
  272. NCPT1:         MOV A,@R0
  273.          CPL A
  274.          ADDC A,#00H
  275.          MOV @R0,A
  276.          INC R0
  277.          DJNZ R7,NCPT1
  278.          MOV R0,B
  279.          RET
  280. ;双字节无符号数加法程序 (R3R4+R6R7)=(R3R4)
  281. ;入口: R3,R4,R6,R7
  282. ;占用资源: ACC
  283. ;堆栈需求: 2字节
  284. ;出口: R3,R4,CF
  285. NADD:         MOV A,R4
  286.          ADD A,R7
  287.          MOV R4,A
  288.          MOV A,R3
  289.          ADDC A,R6
  290.          MOV R3,A
  291.          RET
  292. ;N字节无符号数加法程序 ([R0]+[R1])=([R0])
  293. ;入口: R0,R1,R7
  294. ;占用资源: ACC,B
  295. ;堆栈需求: 2字节
  296. ;出口: R0,CF
  297. NADDN:         MOV B,R0
  298.          CLR C
  299. NADN1:         MOV A,@R0
  300.          ADDC A,@R1
  301.          MOV @R0,A
  302.          INC R0
  303.          INC R1
  304.          DJNZ R7,NADN1
  305.          MOV R0,B
  306.          RET
  307. ;双字节无符号数减法程序 (R3R4-R6R7)=(R3R4)
  308. ;入口: R3,R4,R6,R7
  309. ;占用资源: ACC
  310. ;堆栈需求: 2字节
  311. ;出口: R3,R4
  312. NSUB:         MOV A,R4
  313.          CLR C
  314.          SUBB A,R7
  315.          MOV R4,A
  316.          MOV A,R3
  317.          SUBB A,R6
  318.          MOV R3,A
  319.          RET
  320. ;N字节无符号数减法程序 ([R0]-[R1])=([R0])
  321. ;入口: R0,R1,R7
  322. ;占用资源: ACC,B
  323. ;堆栈需求: 2字节
  324. ;出口: R0,CF
  325. NSUBN:         MOV B,R0
  326.          MOV R7,N
  327.          CLR C
  328. NSUBN1: MOV A,@R0
  329.          SUBB A,@R1
  330.          MOV @R0,A
  331.          INC R0
  332.          INC R1
  333.          DJNZ R7,NSUBN1
  334.          MOV R0,B
  335.          RET
  336. ;单字节无符号数乘法程序 (R3R4*R7)=(R2R3R4)
  337. ;入口: R3,R4,R7
  338. ;占用资源: ACC,B
  339. ;堆栈需求: 2字节
  340. ;出口: R2,R3,R4
  341. NMUL21: MOV A,R4
  342.          MOV B,R7
  343.          MUL AB
  344.          MOV R4,A
  345.          MOV A,B
  346.          XCH A,R3
  347.          MOV B,R7
  348.          MUL AB
  349.          ADD A,R3
  350.          MOV R3,A
  351.          CLR A
  352.          ADDC A,B
  353.          MOV R2,A
  354.          CLR OV
  355.          RET
  356. ;单字节无符号数乘法程序 (R2R3R4*R7)=(R5R2R3R4)
  357. ;入口: R2,R3,R4,R6,R7
  358. ;占用资源: ACC,B
  359. ;堆栈需求: 2字节
  360. ;出口: R5,R2,R3,R4
  361. NMUL31:        MOV A,R4
  362.         MOV B,R7
  363.          MUL AB
  364.          MOV R4,A
  365.          MOV A,B
  366.          XCH A,R3
  367.          MOV B,R7
  368.          MUL AB
  369.          ADD A,R3
  370.          MOV R3,A
  371.          CLR A
  372.          ADDC A,B
  373.          XCH A,R2
  374.          MOV B,R7
  375.          MUL AB
  376.          ADD A,R2
  377.          MOV R2,A
  378.          CLR A
  379.          ADDC A,B
  380.          MOV R5,A
  381.          CLR OV
  382.          RET
  383. ;单字节无符号数乘法程序 (R5R2R3R4*R7)=(R7R5R2R3R4)
  384. ;入口: R5,R2,R3,R4,R7
  385. ;占用资源: ACC,B
  386. ;堆栈需求: 2字节
  387. ;出口: R7,R5,R2,R3,R4
  388. NMUL41: MOV A,R4
  389.          MOV B,R7
  390.          MUL AB
  391.          MOV R4,A
  392.          MOV A,B
  393.          XCH A,R3
  394.          MOV B,R7
  395.          MUL AB
  396.          ADD A,R3
  397.          MOV R3,A
  398.          CLR A
  399.          ADDC A,B
  400.          XCH A,R2
  401.          MOV B,R7
  402.          MUL AB
  403.          ADD A,R2
  404.          MOV R2,A
  405.          CLR A
  406.          ADDC A,B
  407.          XCH A,R5
  408.          MOV B,R7
  409.          MUL AB
  410.          ADD A,R5
  411.          MOV R5,A
  412.          CLR A
  413.          ADDC A,B
  414.          MOV R7,A
  415.          CLR OV
  416.          RET
  417. ;双字节无符号数乘法程序 (R3R4*R6R7)=(R5R2R3R4)
  418. ;入口: R3,R4,R6,R7
  419. ;占用资源: ACC,B
  420. ;堆栈需求: 2字节
  421. ;出口: R5,R2,R3,R4
  422. NMUL22: MOV A,R4
  423.          MOV B,R7
  424.          MUL AB
  425.          XCH A,R4
  426.          MOV R5,B
  427.          MOV B,R6
  428.         MUL AB
  429.          ADD A,R5
  430.          MOV R5,A
  431.          CLR A
  432.          ADDC A,B
  433.          MOV R2,A
  434.          MOV A,R3
  435.          MOV B,R7
  436.          MUL AB
  437.          ADD A,R5
  438.          MOV R5,A
  439.          MOV A,B
  440.          ADDC A,R2
  441.          MOV R2,A
  442.          CLR A
  443.          ADDC A,#00H
  444.          XCH A,R3
  445.          MOV B,R6
  446.          MUL AB
  447.          ADD A,R2
  448.          MOV R2,A
  449.          MOV A,B
  450.          ADDC A,R3
  451.          XCH A,R5
  452.          MOV R3,A
  453.          CLR OV
  454.          RET
  455. ;双字节无符号数乘法程序 (R2R3R4*R6R7)=(R1R5R2R3R4)
  456. ;入口: R2,R3,R4,R6,R7
  457. ;占用资源: ACC,B
  458. ;堆栈需求: 2字节
  459. ;出口: R1,R5,R2,R3,R4
  460. NMUL32: MOV A,R4
  461.          MOV B,R7
  462.          MUL AB
  463.          XCH A,R4
  464.          MOV R5,B
  465.          MOV B,R6
  466.          MUL AB
  467.          ADD A,R5
  468.          MOV R5,A
  469.          CLR A
  470.          ADDC A,B
  471.          MOV R1,A
  472.          MOV A,R3
  473.          MOV B,R7
  474.         MUL AB
  475.          ADD A,R5
  476.          MOV R5,A
  477.          MOV A,B
  478.          ADDC A,R1
  479.          MOV R1,A
  480.          CLR A
  481.          ADDC A,#00H
  482.          XCH A,R3
  483.          MOV B,R6
  484.          MUL AB
  485.          ADD A,R1
  486.          MOV R1,A
  487.          MOV A,B
  488.          ADDC A,R3
  489.          XCH A,R5
  490.          MOV R3,A
  491.          MOV A,R2
  492.          MOV B,R7
  493.          MUL AB
  494.          ADD A,R1
  495.          MOV R1,A
  496.          MOV A,B
  497.          ADDC A,R5
  498.          MOV R5,A
  499.          CLR A
  500.          ADDC A,#00H
  501.          XCH A,R2
  502.          MOV B,R6
  503.          MUL AB
  504.          ADD A,R5
  505.          MOV R5,A
  506.          MOV A,B
  507.          ADDC A,R2
  508.          XCH A,R1
  509.          MOV R2,A
  510.          CLR OV
  511.          RET
  512. ;N字节无符号数乘法程序 ([R0]*[R1])=([R0])
  513. ;入口: R0,R1,M,N
  514. ;占用资源: ACC,B,R2,R5,R6,R7,NCNT
  515. ;堆栈需求: 2字节
  516. ;出口: R0
  517. NMULMN: MOV A,M
  518.          ADD A,R0
  519.          MOV R5,A
  520.         XCH A,R1
  521.          XCH A,R5
  522.          ADD A,N
  523.          XCH A,R0
  524.          MOV R6,A
  525.          MOV B,M
  526.          MOV NCNT,B
  527. NMLMN1: DEC R0
  528.          DEC R1
  529.          CLR A
  530.          XCH A,@R1
  531.          MOV @R0,A
  532.          DJNZ NCNT,NMLMN1
  533.          MOV NCNT,B
  534. NMLMN2: CLR A
  535.          XCH A,@R0
  536.          MOV R2,A
  537.          MOV A,R6
  538.          MOV R0,A
  539.          MOV A,R5
  540.          MOV R1,A
  541.          MOV R7,N
  542.          CLR C
  543. NMLMN3: MOV A,R2
  544.          MOV B,@R1
  545.          INC R1
  546.          MUL AB
  547.          ADDC A,@R0
  548.          MOV @R0,A
  549.          INC R0
  550.          MOV A,B
  551.          ADDC A,@R0
  552.          MOV @R0,A
  553.          DJNZ R7,NMLMN3
  554.          INC R0
  555.          INC R6
  556.          DJNZ NCNT,NMLMN2
  557.          MOV A,R0
  558.          CLR C
  559.          SUBB A,M
  560.          SUBB A,N
  561.          MOV R0,A
  562.          RET
  563. ;单字节无符号除法程序(除数为4bit,1~15) (R3R4/R7)=R3R4 余数R7
  564. ;入口: R3,R4,R7
  565. ;占用资源: ACC,B,F0
  566. ;堆栈需求: 2字节
  567. ;出口: R3,R4,R7,OV  
  568. NDIV24:        MOV A,R3         
  569.         MOV B,R7
  570.         DIV AB
  571.         MOV R3,A
  572.         MOV A,B
  573.         SWAP A
  574.         MOV B,A
  575.         MOV A,R4
  576.         ANL A,#0F0H
  577.         SWAP A
  578.         ORL A,B
  579.         MOV B,R7
  580.         DIV AB
  581.         SWAP A
  582.         PUSH ACC
  583.         MOV A,B
  584.         SWAP A
  585.         MOV B,A
  586.         MOV A,R4
  587.         ANL A,#0FH
  588.         ORL A,B
  589.         MOV B,R7
  590.         DIV AB
  591.         MOV R7,B
  592.         MOV B,A
  593.         POP ACC
  594.         ORL A,B
  595.         MOV R4,A
  596.         RET        
  597. ;单字节无符号除法程序 (R3R4/R7)=(R3)R4 余数R7
  598. ;入口: R3,R4,R7
  599. ;占用资源: ACC,B,F0
  600. ;堆栈需求: 2字节
  601. ;出口: (R3),R4,R7,OV         
  602. NDIV21: MOV A,R3
  603.          MOV B,R7
  604.          DIV AB
  605.          PUSH ACC
  606.          MOV R3,B
  607.          MOV B,#08H
  608. NDV211: CLR C
  609.          MOV A,R4
  610.          RLC A
  611.          MOV R4,A
  612.          MOV A,R3
  613.          RLC A
  614.          MOV R3,A  
  615.          MOV F0,C
  616.          CLR C
  617.          SUBB A,R7
  618.          JB F0,NDV212
  619.          JC NDV213
  620. NDV212: MOV R3,A
  621.          INC R4
  622. NDV213: DJNZ B,NDV211
  623.          POP ACC
  624.          CLR OV
  625.          JZ NDV214
  626.          SETB OV
  627. NDV214: XCH A,R3
  628.          MOV R7,A
  629.          RET
  630. ;单字节无符号除法程序 (R2R3R4/R7)=(R2)R3R4 余数R7
  631. ;入口: R2,R3,R4,R7
  632. ;占用资源: ACC,B,F0
  633. ;堆栈需求: 3字节
  634. ;出口: (R2),R3,R4,R7,OV
  635. NDIV31: MOV A,R2
  636.          MOV B,R7
  637.          DIV AB
  638.          PUSH ACC
  639.          MOV R2,B
  640.          MOV B,#10H
  641. NDV311: CLR C
  642.          MOV A,R4
  643.          RLC A
  644.          MOV R4,A
  645.          MOV A,R3
  646.          RLC A
  647.          MOV R3,A
  648.          MOV A,R2
  649.          RLC A
  650.          MOV R2,A
  651.          MOV F0,C
  652.          CLR C
  653.          SUBB A,R7
  654.          JB F0,NDV312
  655.          JC NDV313
  656. NDV312: MOV R2,A
  657.          INC R4
  658. NDV313: DJNZ B,NDV311
  659.          POP ACC
  660.          CLR OV
  661.          JZ NDV314
  662.          SETB OV
  663. NDV314: XCH A,R2
  664.          MOV R7,A
  665.          RET
  666. ;单字节无符号除法程序 (R5R2R3R4/R7)=(R5)R2R3R4 余数R7
  667. ;入口: R2,R3,R4,R7
  668. ;占用资源: ACC,B,F0
  669. ;堆栈需求: 3字节
  670. ;出口: (R5),R2,R3,R4,R7,OV
  671. NDIV41: MOV A,R5
  672.          MOV B,R7
  673.          DIV AB
  674.          PUSH ACC
  675.          MOV R5,B
  676.          MOV B,#18H
  677. NDV411: CLR C
  678.          MOV A,R4
  679.         RLC A
  680.          MOV R4,A
  681.          MOV A,R3
  682.          RLC A
  683.          MOV R3,A
  684.          MOV A,R2
  685.          RLC A
  686.          MOV R2,A
  687.          MOV A,R5
  688.          RLC A
  689.          MOV R5,A
  690.          MOV F0,C
  691.          CLR C
  692.          SUBB A,R7
  693.          JB F0,NDV412
  694.          JC NDV413
  695. NDV412: MOV R5,A
  696.          INC R4
  697. NDV413: DJNZ B,NDV411
  698.          POP ACC
  699.          CLR OV
  700.          JZ NDV414
  701.          SETB OV
  702. NDV414: XCH A,R5
  703.          MOV R7,A
  704.          RET
  705. ;双字节无符号除法程序 (R5R2R3R4/R6R7)=(R2)R3R4 余数R6R7
  706. ;入口: R5,R2,R3,R4,R6,R7
  707. ;占用资源: ACC,B,F0
  708. ;堆栈需求: 4字节
  709. ;出口: (R2),R3,R4,R6,R7,OV
  710. NDIV42 : MOV A,R1
  711. PUSH ACC
  712. MOV B,#00H
  713. NDV421 : MOV A,R2
  714. CLR C
  715. SUBB A,R7
  716. MOV R1,A
  717. MOV A,R5
  718. SUBB A,R6
  719. JC NDV422
  720. MOV R5,A
  721. MOV A,R1
  722. MOV R2,A
  723. INC B
  724. SJMP NDV421
  725. NDV422 : PUSH B
  726. MOV B,#10H
  727. NDV423 : CLR C
  728. MOV A,R4
  729. RLC A
  730. MOV R4,A
  731. MOV A,R3
  732. RLC A
  733. MOV R3,A
  734. MOV A,R2
  735. RLC A
  736. MOV R2,A
  737. XCH A,R5
  738. RLC A
  739. XCH A,R5
  740. MOV F0,C
  741. CLR C
  742. SUBB A,R7
  743. MOV R1,A
  744. MOV A,R5
  745. SUBB A,R6
  746. JB F0,NCV424
  747. JC NDV425
  748. NCV424 : MOV R5,A
  749. MOV A,R1
  750. MOV R2,A
  751. INC R4
  752. NDV425 : DJNZ B,NDV423
  753. POP ACC
  754. CLR OV
  755. JNZ NDV426
  756. SETB OV
  757. NDV426 : XCH A,R2
  758. MOV R7,A
  759. MOV A,R5
  760. MOV R6,A
  761. POP ACC
  762. MOV R1,A
  763. RET
  764. ;N字节无符号除法程序(组合) ([R0]/[R1])=([R0])
  765. ;入口: R0,R1,M,N
  766. ;占用资源: ACC,R2,R3,R4,R5,R7,NCNT,F0,NADDN,NSUBBN,NRLCN
  767. ;堆栈需求: 4字节
  768. ;出口: R0
  769. NDIVMN : MOV A,M
  770. CLR C
  771. SUBB A,N
  772. MOV NCNT,A
  773. ADD A,R0
  774. MOV R4,A
  775. XCH A,R0
  776. MOV R3,A
  777. MOV A,R1
  778. MOV R5,A
  779. MOV R2,#00H
  780. NDVMN1 : MOV R7,N
  781. LCALL NSUBN
  782. MOV A,R5
  783. MOV R1,A
  784. JC NDVMN2
  785. INC R2
  786. SJMP NDVMN1
  787. NDVMN2 : MOV R7,N
  788. LCALL NADDN
  789. MOV A,NCNT
  790. SWAP A
  791. RR A
  792. MOV NCNT,A
  793. NDVMN3 : MOV A,R3
  794. MOV R0,A
  795. MOV R7,M
  796. LCALL NRLCN
  797. MOV F0,C
  798. MOV A,R4
  799. MOV R0,A
  800. MOV A,R5
  801. MOV R1,A
  802. MOV R7,N
  803. LCALL NSUBN
  804. JB F0,NDVMN4
  805. JC NDVMN5
  806. NDVMN4 : MOV A,R3
  807. MOV R0,A
  808. INC @R0
  809. SJMP NDVMN6
  810. NDVMN5 : MOV A,R5
  811. MOV R1,A
  812. MOV R7,N
  813. LCALL NADDN
  814. NDVMN6 : DJNZ NCNT,NDVMN3
  815. MOV A,R4
  816. MOV R1,A
  817. MOV A,R2
  818. MOV @R1,A
  819. MOV A,R3
  820. MOV R0,A
  821. RET
  822. ;N字节无符号除法程序(集成) ([R0]/R[1])=([R0])
  823. ;入口: R0,R1,M,N
  824. ;占用资源: ACC,R2,R3,R4,R5,R7,F0
  825. ;堆栈需求: 2字节
  826. ;出口: R0
  827. NDIVMN : MOV A,M
  828. CLR C
  829. SUBB A,N
  830. MOV B,A
  831. ADD A,R0
  832. MOV R4,A
  833. XCH A,R0
  834. MOV R3,A
  835. MOV A,R1
  836. MOV R5,A
  837. MOV R2,#00H
  838. NDVMN1 : MOV R7,N
  839. CLR C
  840. NDVMN2 : MOV A,@R0
  841. SUBB A,@R1
  842. MOV @R0,A
  843. INC R0
  844. INC R1
  845. DJNZ R7,NDVMN2
  846. MOV A,R4
  847. MOV R0,A
  848. MOV A,R5
  849. MOV R1,A
  850. JC NDVMN3
  851. INC R2
  852. SJMP NDVMN1
  853. NDVMN3 : MOV R7,N
  854. CLR C
  855. NDVMN4 : MOV A,@R0
  856. ADDC A,@R1
  857. MOV @R0,A
  858. INC R0
  859. INC R1
  860. DJNZ R7,NDVMN4
  861. MOV A,#08H
  862. MUL AB
  863. MOV B,A
  864. NDVMN5 : MOV A,R3
  865. MOV R0,A
  866. MOV R7,M
  867. CLR C
  868. NDVMN6 : MOV A,@R0
  869. RLC A
  870. MOV @R0,A
  871. INC R0
  872. DJNZ R7,NDVMN6
  873. MOV F0,C
  874. MOV A,R4
  875. MOV R0,A
  876. MOV A,R5
  877. MOV R1,A
  878. MOV R7,N
  879. CLR C
  880. NDVMN7 : MOV A,@R0
  881. SUBB A,@R1
  882. MOV @R0,A
  883. INC R0
  884. INC R1
  885. DJNZ R7,NDVMN7
  886. JB F0,NDVMNB
  887. JC NDVMN8
  888. NDVMNB : MOV A,R3
  889. MOV R0,A
  890. INC @R0
  891. SJMP NDVMNA
  892. NDVMN8 : MOV R7,N
  893. MOV A,R4
  894. MOV R0,A
  895. MOV A,R5
  896. MOV R1,A
  897. CLR C
  898. NDVMN9 : MOV A,@R0
  899. ADDC A,@R1
  900. MOV @R0,A
  901. INC R0
  902. INC R1
  903. DJNZ R7,NDVMN9
  904. NDVMNA : DJNZ B,NDVMN5
  905. MOV A,M
  906. CLR C
  907. SUBB A,N
  908. ADD A,R3
  909. MOV R1,A
  910. MOV A,R2
  911. MOV @R1,A
  912. MOV A,R3
  913. MOV R0,A
  914. RET
  915. ;N字节数据左移程序 RLC([R0])=(CF[R0])
  916. ;入口: R0,R7
  917. ;占用资源: ACC,B
  918. ;堆栈需求: 2字节
  919. ;出口: R0,CF
  920. NRLCN: MOV B,R0
  921. CLR C
  922. NRLN1: MOV A,@R0
  923. RLC A
  924. MOV @R0,A
  925. INC R0
  926. DJNZ R7,NRLN1
  927. MOV R0,B
  928. RET
  929. ;原码有符号双字节减法程序 (R3R4-R6R7)=R3R4
  930. ;入口: R3,R4,R6,R7
  931. ;占用资源: ACC,DADD
  932. ;堆栈需求: 6字节
  933. ;出口: R3,R4,OV
  934. DSUB : MOV A,R6
  935. CPL ACC.7
  936. MOV R6,A
  937. LCALL DADD
  938. RET
  939. ;原码有符号双字节加法程序 (R3R4+R6R7)=R3R4
  940. ;入口: R3,R4,R6,R7
  941. ;占用资源: ACC,SR0,NADD,NSUB,CMPT
  942. ;堆栈需求: 4字节
  943. ;出口: R3,R4,OV
  944. DADD : MOV A,R3
  945. MOV C,ACC.7
  946. MOV SR0,C
  947. XRL A,R6
  948. MOV C,ACC.7
  949. MOV A,R3
  950. CLR ACC.7
  951. MOV R3,A
  952. MOV A,R6
  953. CLR ACC.7
  954. MOV R6,A
  955. JC DAB2
  956. LCALL NADD
  957. MOV A,R3
  958. JB ACC.7,DABE
  959. DAB1 : MOV C,SR0
  960. MOV ACC.7,C
  961. MOV R3,A
  962. CLR OV
  963. RET
  964. DABE : SETB OV
  965. RET
  966. DAB2 : LCALL NSUB
  967. MOV A,R3
  968. JNB ACC.7,DAB1
  969. LCALL CMPT
  970. CPL SR0
  971. SJMP DAB1
  972. ;原码有符号双字节乘法程序 (R3R4*R6R7)=(R5R2R3R4)
  973. ;入口: R3,R4,R6,R7
  974. ;占用资源: ACC,SR0,NMUL22
  975. ;堆栈需求: 4字节
  976. ;出口: R5,R2,R3,R4
  977. IMUL : MOV A,R3
  978. XRL A,R6
  979. MOV C,ACC.7
  980. MOV SR0,C
  981. MOV A,R3
  982. CLR ACC.7
  983. MOV R3,A
  984. MOV A,R6
  985. CLR ACC.7
  986. MOV R6,A
  987. LCALL NMUL22
  988. MOV A,R5
  989. MOV C,SR0
  990. MOV ACC.7,C
  991. MOV R5,A
  992. RET
  993. ;原码有符号双字节除法程序 (R5R2R3R4/R6R7)=(R3R4) 余数(R6R7)
  994. ;入口: R5,R2,R3,R4
  995. ;占用资源: ACC,SR0,NDIV42
  996. ;堆栈需求: 6字节
  997. ;出口: R3,R4,R6,R7,OV
  998. IDIV : MOV A,R5
  999. XRL A,R6
  1000. MOV C,ACC.7
  1001. MOV SR0,C
  1002. MOV A,R5
  1003. CLR ACC.7
  1004. MOV R5,A
  1005. MOV A,R6
  1006. CLR ACC.7
  1007. MOV R6,A
  1008. LCALL NDIV42
  1009. MOV A,R3
  1010. JB ACC.7,IDIVE
  1011. JB OV,IDIVE
  1012. MOV C,SR0
  1013. MOV ACC.7,C
  1014. MOV R3,A
  1015. RET
  1016. IDIVE: SETB OV
  1017. RET
  1018. ;单字节顺序查找程序
  1019. ;入口: R0,R1,A,R7
  1020. ;占用资源: B
  1021. ;堆栈需求: 2字节
  1022. ;出口: R0,R1,A
  1023. FINDB1 : MOV B,A
  1024. MOV DPL,R1
  1025. MOV DPH,R0
  1026. FINDB11 : MOVX A,@DPTR
  1027. CJNE A,B,FINDB12
  1028. MOV R1,DPL
  1029. MOV R0,DPH
  1030. CLR A
  1031. RET
  1032. FINDB12 : INC DPTR
  1033. DJNZ R7,FINDB11
  1034. MOV A,#0FFH
  1035. RET
  1036. ;单字节顺序查找程序
  1037. ;入口: R0,R1,A,R6,R7
  1038. ;占用资源: B
  1039. ;堆栈需求: 2字节
  1040. ;出口: R0,R1,A
  1041. FINDB2 : MOV B,A
  1042. MOV DPL,R1
  1043. MOV DPH,R0
  1044. MOV A,R7
  1045. JZ FINDB21
  1046. INC R6
  1047. FINDB21 : MOVX A,@DPTR
  1048. CJNE A,B,FINDB22
  1049. MOV R1,DPL
  1050. MOV R0,DPH
  1051. CLR A
  1052. RET
  1053. FINDB22 : INC DPTR
  1054. DJNZ R7,FINDB21
  1055. DJNZ R6,FINDB21
  1056. MOV A,#0FFH
  1057. RET
  1058. ;双字节字符串顺序查找程序
  1059. ;入口: R0,R1,R3,R4,R7
  1060. ;占用资源: ACC,B
  1061. ;堆栈需求: 2字节
  1062. ;出口: R0,R1,A
  1063. FINDS1 : MOV DPL,R1
  1064. MOV DPH,R0
  1065. FINDS11 : MOVX A,@DPTR
  1066. INC DPTR
  1067. CLR C
  1068. SUBB A,R4
  1069. JNZ FINDS12
  1070. MOVX A,@DPTR
  1071. SUBB A,R3
  1072. JNZ FINDS12
  1073. MOV A,DPL
  1074. CLR C
  1075. SUBB A,#01H
  1076. MOV R1,A
  1077. MOV A,DPH
  1078. SUBB A,#00H
  1079. MOV R0,A
  1080. CLR A
  1081. RET
  1082. FINDS12 : DJNZ R7,FINDS11
  1083. MOV A,#0FFH
  1084. RET
  1085. ;双字节字符串顺序查找程序
  1086. ;入口: R0,R1,R3,R4,R6,R7
  1087. ;占用资源: ACC,B
  1088. ;堆栈需求: 2字节
  1089. ;出口: R0,R1,A
  1090. FINDS2 : MOV DPL,R1
  1091. MOV DPH,R0
  1092. MOV A,R7
  1093. JZ FINDS21
  1094. INC R6
  1095. FINDS21 : MOVX A,@DPTR
  1096. INC DPTR
  1097. CLR C
  1098. SUBB A,R4
  1099. JNZ FINDS22
  1100. MOVX A,@DPTR
  1101. SUBB A,R3
  1102. JNZ FINDS22
  1103. MOV A,DPL
  1104. CLR C
  1105. SUBB A,#01H
  1106. MOV R1,A
  1107. MOV A,DPH
  1108. SUBB A,#00H
  1109. MOV R0,A
  1110. CLR A
  1111. RET
  1112. FINDS22 : DJNZ R7,FINDS21
  1113. DJNZ R6,FINDS21
  1114. MOV A,#0FFH
  1115. RET
  1116. ;N字节字符串顺序查找程序
  1117. ;入口: ADDPH,ADDPL,R0,R6,R7,N
  1118. ;占用资源: ACC,B,R2,NCNT
  1119. ;堆栈需求: 2字节
  1120. ;出口: ADDPH,ADDPL,A
  1121. FINDN: MOV A,R0
  1122. MOV R2,A
  1123. MOV A,ADDPL
  1124. MOV DPL,A
  1125. MOV A,ADDPH
  1126. MOV DPH,A
  1127. MOV A,R7
  1128. JZ FINDN1
  1129. INC R6
  1130. FINDN1 : MOV A,R2
  1131. MOV R0,A
  1132. MOV A,N
  1133. MOV NCNT,A
  1134. FINDN2 : MOVX A,@DPTR
  1135. CLR C
  1136. SUBB A,@R0
  1137. JNZ FINDN3
  1138. INC DPTR
  1139. INC R0
  1140. DJNZ NCNT,FINDN2
  1141. MOV A,DPL
  1142. CLR C
  1143. SUBB A,N
  1144. MOV ADDPL,A
  1145. MOV A,DPH
  1146. SUBB A,#00H
  1147. MOV ADDPH,A
  1148. CLR A
  1149. RET
  1150. FINDN3 : CLR C
  1151. MOV A,R0
  1152. SUBB A,R2
  1153. JNZ FINDN4
  1154. INC DPTR
  1155. FINDN4 : DJNZ R7,FINDN1
  1156. DJNZ R6,FINDN1
  1157. MOV A,#0FFH
  1158. RET
  1159. ;单字节最值查找程序
  1160. ;入口: R0,R1,R6,R7
  1161. ;占用资源: ACC,B
  1162. ;堆栈需求: 2字节
  1163. ;出口: R0(最大值),R1(最小值),R2,R3,R4,R5
  1164. FMAMIB : MOV DPL,R1
  1165. MOV DPH,R0
  1166. MOVX A,@DPTR
  1167. MOV R0,A
  1168. MOV R1,A
  1169. MOV A,DPL
  1170. MOV R3,A
  1171. MOV R5,A
  1172. MOV A,DPH
  1173. MOV R2,A
  1174. MOV R4,A
  1175. MOV A,R7
  1176. JZ FMMB1
  1177. INC R6
  1178. FMMB1: MOVX A,@DPTR
  1179. MOV B,A
  1180. SETB C
  1181. SUBB A,R0
  1182. JC FMMB2
  1183. MOV R0,B
  1184. MOV R3,DPL
  1185. MOV R2,DPH
  1186. SJMP FMMB3
  1187. FMMB2: MOV A,B
  1188. CLR C
  1189. SUBB A,R1
  1190. JNC FMMB3
  1191. MOV R1,B
  1192. MOV R5,DPL
  1193. MOV R4,DPH
  1194. FMMB3: INC DPTR
  1195. DJNZ R7,FMMB1
  1196. DJNZ R6,FMMB1
  1197. RET
  1198. ;浮点数顺序查找程序
  1199. ;入口: R0,R1,R2,R3,R4,R6,R7
  1200. ;占用资源: B,NCNT,FCMP
  1201. ;堆栈需求: 2字节
  1202. ;出口: R0,R1,A
  1203. FINDF: MOV DPL,R1
  1204. MOV DPH,R0
  1205. MOV A,R7
  1206. MOV B,A
  1207. MOV NCNT,R6
  1208. JZ FINDF1
  1209. INC NCNT
  1210. FINDF1 : MOVX A,@DPTR
  1211. INC DPTR
  1212. MOV R5,A
  1213. MOVX A,@DPTR
  1214. INC DPTR
  1215. MOV R6,A
  1216. MOVX A,@DPTR
  1217. INC DPTR
  1218. MOV R7,A
  1219. LCALL FCMP
  1220. JNZ FINDF2
  1221. MOV A,DPL
  1222. CLR C
  1223. SUBB A,#03H
  1224. MOV R1,A
  1225. MOV A,DPH
  1226. SUBB A,#00H
  1227. MOV R0,A
  1228. CLR A
  1229. RET
  1230. FINDF2 : DJNZ B,FINDF1
  1231. DJNZ NCNT,FINDF1
  1232. MOV A,#0FFH
  1233. RET
  1234. ;浮点数最值查找程序
  1235. ;入口: ADDPH,ADDPL,R6,R7
  1236. ;占用资源: ACC,B,NCNT,ITEMOV,EBMOV,MOVB,MOVR1,FCMP
  1237. ;堆栈需求: 5字节
  1238. ;出口: [R0](最大值),[R1](最小值),R2,R3,R4,R5
  1239. FMAMIF : MOV A,ADDPL
  1240. MOV R3,A
  1241. MOV R5,A
  1242. MOV DPL,A
  1243. MOV A,ADDPH
  1244. MOV R2,A
  1245. MOV R4,A
  1246. MOV DPH,A
  1247. MOV B,R7
  1248. MOV R7,#03H
  1249. LCALL ITEMOV
  1250. MOV R7,#03H
  1251. LCALL IBMOV
  1252. MOV A,B
  1253. JZ FMMF1
  1254. INC NCNT
  1255. FMMF1: PUSH B
  1256. MOVX A,@DPTR
  1257. INC DPTR
  1258. MOV R2,A
  1259. MOVX A,@DPTR
  1260. INC DPTR
  1261. MOV R3,A
  1262. MOVX A,@DPTR
  1263. INC DPTR
  1264. MOV R4,A
  1265. LCALL MOVR1
  1266. LCALL FCMP
  1267. JNC FMMF2
  1268. MOV A,R0
  1269. XCH A,R1
  1270. MOV R0,A
  1271. LCALL MOVB
  1272. MOV R5,DPL
  1273. MOV R4,DPH
  1274. MOV A,R0
  1275. XCH A,R1
  1276. MOV R0,A
  1277. SJMP FMMF3
  1278. FMMF2: MOV A,R0
  1279. XCH A,R1
  1280. MOV R0,A
  1281. LCALL MOVR1
  1282. LCALL FCMP
  1283. MOV A,R0
  1284. XCH A,R1
  1285. MOV R0,A
  1286. JZ FMMF3
  1287. JC FMMF3
  1288. LCALL MOVB
  1289. MOV R3,DPL
  1290. MOV R2,DPH
  1291. FMMF3: POP B
  1292. DJNZ B,FMMF1
  1293. DJNZ NCNT,FMMF1
  1294. RET
  1295. ;单字节折半查找程序
  1296. ;入口: A,R0,R1,R6,R7
  1297. ;占用资源: B,R2
  1298. ;堆栈需求: 2字节
  1299. ;出口: R0,R1
  1300. SEARCHB : MOV B,A
  1301. MOV A,R1
  1302. ADD A,R7
  1303. MOV R7,A
  1304. MOV A,R0
  1305. ADDC A,R6
  1306. MOV R6,A
  1307. MOV A,R7
  1308. SUBB A,#01H
  1309. MOV R7,A
  1310. JNC SECH1
  1311. DEC R6
  1312. SECH1: MOV A,R7
  1313. CLR C
  1314. SUBB A,R1
  1315. MOV A,R6
  1316. SUBB A,R0
  1317. JNC SECH2
  1318. MOV A,#0FFH
  1319. RET
  1320. SECH2: MOV A,R7
  1321. ADD A,R1
  1322. MOV R2,A
  1323. MOV A,R6
  1324. ADDC A,R0
  1325. RRC A
  1326. MOV DPH,A
  1327. MOV A,R2
  1328. RRC A
  1329. MOV DPL,A
  1330. MOVX A,@DPTR
  1331. CLR C
  1332. SUBB A,B
  1333. JNC SECH3
  1334. INC DPTR
  1335. MOV R0,DPH
  1336. MOV R1,DPL
  1337. SJMP SECH1
  1338. SECH3: JZ SECH5
  1339. MOV A,DPL
  1340. SUBB A,#01H
  1341. MOV R7,A
  1342. JNC SECH4
  1343. MOV R6,DPH
  1344. DEC R6
  1345. SECH4: SJMP SECH1
  1346. SECH5: MOV R0,DPH
  1347. MOV R1,DPL
  1348. CLR A
  1349. RET
  1350. ;辛普生积分程序
  1351. ;入口: DPTR,N,COUNT
  1352. ;占用资源: ACC,R3,R4,R6,R7
  1353. ;堆栈需求: 2字节
  1354. ;出口: R3,R4
  1355. SJF : MOV R7,N
  1356. MOVX A,@DPTR
  1357. INC DPTR
  1358. MOV R4,A
  1359. MOV R3,#00H
  1360. DEC R7
  1361. SJF1 : MOVX A,@DPTR
  1362. INC DPTR
  1363. CLR C
  1364. RLC A
  1365. MOV R6,A
  1366. CLR A
  1367. RLC A
  1368. XCH A,R7
  1369. JNB ACC.0,SJF2
  1370. XCH A,R6
  1371. RLC A
  1372. XCH A,R6
  1373. XCH A,R7
  1374. RLC A
  1375. XCH A,R7
  1376. SJF2 : XCH A,R7
  1377. XCH A,R6
  1378. ADD A,R4
  1379. MOV R4,A
  1380. MOV A,R6
  1381. ADDC A,R3
  1382. MOV R3,A
  1383. DJNZ R7,SJF1
  1384. SJF3 : MOVX A,@DPTR
  1385. ADD A,R4
  1386. MOV R4,A
  1387. CLR A
  1388. ADDC A,R3
  1389. MOV R3,A
  1390. MOV R7,#COUNT
  1391. LCALL NMUL21
  1392. MOV A,N
  1393. MOV B,#03H
  1394. MUL AB
  1395. MOV R7,A
  1396. LCALL NDIV31
  1397. RET
  1398. ;内部RAM数据排序程序(升序)
  1399. ;入口: R0(起始地址),N(数据个数)
  1400. ;占用资源: ACC,B,R5,R6,R7
  1401. ;堆栈需求: 2字节
  1402. ;出口: R0
  1403. ISELSORT : MOV R7,N
  1404. DEC R7
  1405. ISST1: MOV A,R7
  1406. MOV R6,A
  1407. MOV A,R0
  1408. MOV R1,A
  1409. MOV R2,A
  1410. MOV B,@R1
  1411. ISST2: INC R1
  1412. MOV A,@R1
  1413. CLR C
  1414. SUBB A,B
  1415. JC ISST3
  1416. MOV A,R1
  1417. MOV R2,A
  1418. MOV B,@R1
  1419. ISST3: DJNZ R6,ISST2
  1420. MOV A,B
  1421. XCH A,@R1
  1422. MOV B,R2
  1423. MOV R1,B
  1424. MOV @R1,A
  1425. DJNZ R7,ISST1
  1426. RET
  1427. ;外部RAM数据排序程序(升序)
  1428. ;入口: ADDPH,ADDPL(起始地址),N(数据个数)
  1429. ;占用资源: ACC,B,R0,R1,R5,R7
  1430. ;堆栈需求: 2字节
  1431. ;出口: ADDPH-ADDPL
  1432. ESELSORT : MOV R7,N
  1433. DEC R7
  1434. ESST1: MOV A,R7
  1435. MOV R6,A
  1436. MOV DPL,ADDPL
  1437. MOV R1,DPL
  1438. MOV DPH,ADDPH
  1439. MOV R0,DPH
  1440. MOVX A,@DPTR
  1441. MOV B,A
  1442. ESST2: INC DPTR
  1443. MOVX A,@DPTR
  1444. CLR C
  1445. SUBB A,B
  1446. JC ESST3
  1447. MOV R0,DPL
  1448. MOV R1,DPH
  1449. MOVX A,@DPTR
  1450. MOV B,A
  1451. ESST3: DJNZ R6,ESST2
  1452. MOVX A,@DPTR
  1453. XCH A,B
  1454. MOVX @DPTR,A
  1455. MOV DPL,R0
  1456. MOV DPH,R1
  1457. MOV A,B
  1458. MOVX @DPTR,A
  1459. DJNZ R7,ESST1
  1460. RET
  1461. ;外部RAM浮点数排序程序(升序)
  1462. ;入口: ADDPH,ADDPL(起始地址),N(数据个数)
  1463. ;占用资源: ACC,B,R0,R1,R2,R3,R4,R5,R6,R7,NCNT
  1464. ;堆栈需求: 5字节
  1465. ;出口: ADDPH,ADDPL
  1466. FSORT: MOV A,N
  1467. MOV NCNT,A
  1468. DEC NCNT
  1469. FST1 : MOV B,NCNT
  1470. MOV DPL,ADDPL
  1471. MOV R1,DPL
  1472. MOV DPH,ADDPH
  1473. MOV R0,DPH
  1474. MOVX A,@DPTR
  1475. MOV R2,A
  1476. INC DPTR
  1477. MOVX A,@DPTR
  1478. MOV R3,A
  1479. INC DPTR
  1480. MOVX A,@DPTR
  1481. MOV R4,A
  1482. FST2 : INC DPTR
  1483. MOVX A,@DPTR
  1484. MOV R5,A
  1485. INC DPTR
  1486. MOVX A,@DPTR
  1487. MOV R6,A
  1488. INC DPTR
  1489. MOVX A,@DPTR
  1490. MOV R7,A
  1491. PUSH B
  1492. LCALL FCMP
  1493. POP B
  1494. JNC FST4
  1495. MOV A,DPL
  1496. CLR C
  1497. SUBB A,#02H
  1498. MOV R1,A
  1499. MOV R0,DPH
  1500. JNC FST3
  1501. DEC R0
  1502. FST3 : MOV A,R5
  1503. MOV R2,A
  1504. MOV A,R6
  1505. MOV R3,A
  1506. MOV A,R7
  1507. MOV R4,A
  1508. FST4 : DJNZ B,FST2
  1509. MOV A,DPL
  1510. CLR C
  1511. SUBB A,#02H
  1512. MOV DPL,A
  1513. JNC FST5
  1514. DEC DPH
  1515. FST5 : MOV A,R2
  1516. MOVX @DPTR,A
  1517. INC DPTR
  1518. MOV A,R3
  1519. MOVX @DPTR,A
  1520. INC DPTR
  1521. MOV A,R4
  1522. MOVX @DPTR,A
  1523. MOV A,R0
  1524. MOV P2,A
  1525. MOV A,R5
  1526. MOVX @R1,A
  1527. INC R1
  1528. MOV A,R6
  1529. MOVX @R1,A
  1530. INC R1
  1531. MOV A,R7
  1532. MOVX @R1,A
  1533. DJNZ NCNT,FST1
  1534. RET
  1535. ;BCD小数转换为二进制小数(2位)
  1536. ;入口: R0(低位首址),R7
  1537. ;占用资源: ACC,B,R5
  1538. ;堆栈需求: 2字节
  1539. ;出口: R3,R4
  1540. PDTB : CLR A
  1541. MOV R3,A
  1542. MOV R4,A
  1543. PDB1 : MOV A,R3
  1544. MOV B,#9AH
  1545. MUL AB
  1546. MOV R5,B
  1547. XCH A,R4
  1548. MOV B,#19H
  1549. MUL AB
  1550. ADD A,R4
  1551. MOV A,R5
  1552. ADDC A,B
  1553. MOV R5,A
  1554. MOV A,@R0
  1555. MOV B,#9AH
  1556. MUL AB
  1557. ADD A,R5
  1558. MOV R4,A
  1559. CLR A
  1560. ADDC A,B
  1561. XCH A,R3
  1562. MOV B,#19H
  1563. MUL AB
  1564. ADD A,R4
  1565. MOV R4,A
  1566. MOV A,B
  1567. ADDC A,R3
  1568. MOV R3,A
  1569. MOV A,@R0
  1570. MOV B,#19H
  1571. MUL AB
  1572. ADD A,R3
  1573. MOV R3,A
  1574. DEC R0
  1575. DJNZ R7,PDB1
  1576. RET
  1577. ;BCD小数转换为二进制小数(N位)
  1578. ;入口: R1(低位首址),M,N
  1579. ;占用资源: ACC,B,R2,R3,R7
  1580. ;堆栈需求: 2字节
  1581. ;出口: R0
  1582. PDTBMN : MOV A,R0
  1583. MOV R2,A
  1584. MOV A,R1
  1585. MOV R3,A
  1586. MOV B,N
  1587. CLR A
  1588. PDBMN1 : MOV @R0,A
  1589. INC R0
  1590. DJNZ B,PDBMN1
  1591. MOV A,N
  1592. SWAP A
  1593. RR A
  1594. MOV R7,A
  1595. PDBMN2 : MOV A,R2
  1596. MOV R0,A
  1597. MOV A,R3
  1598. MOV R1,A
  1599. MOV B,M
  1600. CLR C
  1601. PDBMN3 : MOV A,@R1
  1602. ADDC A,@R1
  1603. DA A
  1604. JNB ACC.4,PDBMN4
  1605. SETB C
  1606. CLR ACC.4
  1607. PDBMN4 : MOV @R1,A
  1608. INC R1
  1609. DJNZ B,PDBMN3
  1610. MOV B,N
  1611. PDBMN5 : MOV A,@R0
  1612. RLC A
  1613. MOV @R0,A
  1614. INC R0
  1615. DJNZ B,PDBMN5
  1616. DJNZ R7,PDBMN2
  1617. MOV A,R2
  1618. MOV R0,A
  1619. RET
  1620. ;BCD整数转换为二进制整数(1位)
  1621. ;入口: R0(高位地址),R7
  1622. ;占用资源: ACC,B
  1623. ;堆栈需求: 2字节
  1624. ;出口: R4
  1625. IDTB1: CLR A
  1626. MOV R4,A
  1627. IDB11: MOV A,R4
  1628. MOV B,#0AH
  1629. MUL AB
  1630. ADD A,@R0
  1631. INC R0
  1632. MOV R4,A
  1633. DJNZ R7,IDB11
  1634. RET
  1635. ;BCD整数转换为二进制整数(2位)
  1636. ;入口: R0(高位地址),R7
  1637. ;占用资源: ACC,B
  1638. ;堆栈需求: 2字节
  1639. ;出口: R3,R4
  1640. IDTB2: CLR A
  1641. MOV R3,A
  1642. MOV R4,A
  1643. IDB21: MOV A,R4
  1644. MOV B,#0AH
  1645. MUL AB
  1646. MOV R4,A
  1647. MOV A,B
  1648. XCH A,R3
  1649. MOV B,#0AH
  1650. MUL AB
  1651. ADD A,R3
  1652. MOV R3,A
  1653. MOV A,R4
  1654. ADD A,@R0
  1655. INC R0
  1656. MOV R4,A
  1657. CLR A
  1658. ADDC A,R3
  1659. MOV R3,A
  1660. DJNZ R7,IDB21
  1661. RET
  1662. ;BCD整数转换为二进制整数(3位)
  1663. ;入口: R0(高位地址),R7
  1664. ;占用资源: ACC,B
  1665. ;堆栈需求: 2字节
  1666. ;出口: R2,R3,R4
  1667. IDTB3: CLR A
  1668. MOV R2,A
  1669. MOV R3,A
  1670. MOV R4,A
  1671. IDB31: MOV A,R4
  1672. MOV B,#0AH
  1673. MUL AB
  1674. MOV R4,A
  1675. MOV A,B
  1676. XCH A,R3
  1677. MOV B,#0AH
  1678. MUL AB
  1679. ADD A,R3
  1680. MOV R3,A
  1681. CLR A
  1682. ADDC A,B
  1683. XCH A,R2
  1684. MOV B,#0AH
  1685. MUL AB
  1686. ADD A,R2
  1687. MOV R2,A
  1688. MOV A,R4
  1689. ADD A,@R0
  1690. INC R0
  1691. MOV R4,A
  1692. CLR A
  1693. ADDC A,R3
  1694. MOV R3,A
  1695. CLR A
  1696. ADDC A,R2
  1697. MOV R2,A
  1698. DJNZ R7,IDB31
  1699. RET
  1700. ;BCD整数转换为二进制整数(N位)
  1701. ;入口: R1(高位地址),M,N
  1702. ;占用资源: ACC,B,R2,R7,NCNT,F0
  1703. ;堆栈需求: 2字节
  1704. ;出口: R0
  1705. IDTBMN : MOV A,R0
  1706. MOV R2,A
  1707. MOV B,N
  1708. CLR A
  1709. IDBMN1 : MOV @R0,A
  1710. INC R0
  1711. DJNZ B,IDBMN1
  1712. MOV A,R2
  1713. MOV R0,A
  1714. MOV A,M
  1715. MOV NCNT,A
  1716. IDBMN2 : MOV R7,N
  1717. CLR A
  1718. CLR F0
  1719. IDBMN3 : XCH A,@R0
  1720. MOV B,#0AH
  1721. MUL AB
  1722. MOV C,F0
  1723. ADDC A,@R0
  1724. MOV F0,C
  1725. MOV @R0,A
  1726. INC R0
  1727. MOV A,B
  1728. DJNZ R7,IDBMN3
  1729. MOV A,R2
  1730. MOV R0,A
  1731. MOV A,@R1
  1732. INC R1
  1733. ADD A,@R0
  1734. MOV @R0,A
  1735. DJNZ NCNT,IDBMN2
  1736. RET
  1737. ;二进制小数(2位)转换为十进制小数(分离BCD码)
  1738. ;入口: R3,R4,R7
  1739. ;占用资源: ACC,B
  1740. ;堆栈需求: 3字节
  1741. ;出口: R0
  1742. PBTD : MOV A,R7
  1743. PUSH ACC
  1744. PBD1 : MOV A,R4
  1745. MOV B,#0AH
  1746. MUL AB
  1747. MOV R4,A
  1748. MOV A,B
  1749. XCH A,R3
  1750. MOV B,#0AH
  1751. MUL AB
  1752. ADD A,R3
  1753. MOV R3,A
  1754. CLR A
  1755. ADDC A,B
  1756. MOV @R0,A
  1757. INC R0
  1758. DJNZ R7,PBD1
  1759. POP ACC
  1760. MOV R7,A
  1761. MOV A,R0
  1762. CLR C
  1763. SUBB A,R7
  1764. MOV R0,A
  1765. RET
  1766. ;二进制小数(M位)转换为十进制小数(分离BCD码)
  1767. ;入口: R1,M,N
  1768. ;占用资源: ACC,B,R2,R3,R7,NCNT
  1769. ;堆栈需求: 2字节
  1770. ;出口: R0
  1771. PBTDMN : MOV A,R0
  1772. MOV R2,A
  1773. MOV A,R1
  1774. MOV R3,A
  1775. MOV A,N
  1776. MOV NCNT,A
  1777. PBDMN1 : MOV R7,M
  1778. CLR A
  1779. CLR F0
  1780. PBDMN2 : XCH A,@R1
  1781. MOV B,#0AH
  1782. MUL AB
  1783. MOV C,F0
  1784. ADDC A,@R1
  1785. MOV F0,C
  1786. MOV @R1,A
  1787. INC R1
  1788. MOV A,B
  1789. DJNZ R7,PBDMN2
  1790. ADDC A,#00H
  1791. MOV @R0,A
  1792. INC R0
  1793. MOV A,R3
  1794. MOV R1,A
  1795. DJNZ NCNT,PBDMN1
  1796. MOV A,R2
  1797. MOV R0,A
  1798. RET
  1799. ;二进制整数(2位)转换为十进制整数(分离BCD码)
  1800. ;入口: R3,R4
  1801. ;占用资源: ACC,R2,NDIV31
  1802. ;堆栈需求: 5字节
  1803. ;出口: R0,NCNT
  1804. IBTD21 : MOV NCNT,#00H
  1805. MOV R2,#00H
  1806. IBD211 : MOV R7,#0AH
  1807. LCALL NDIV31
  1808. MOV A,R7
  1809. MOV @R0,A
  1810. INC R0
  1811. INC NCNT
  1812. MOV A,R3
  1813. ORL A,R4
  1814. JNZ IBD211
  1815. MOV A,R0
  1816. CLR C
  1817. SUBB A,NCNT
  1818. MOV R0,A
  1819. RET
  1820. ;二进制整数(2位)转换为十进制整数(组合BCD码)
  1821. ;入口: R3,R4
  1822. ;占用资源: ACC,B,R7
  1823. ;堆栈需求: 3字节
  1824. ;出口: R0
  1825. IBTD22 : MOV A,R0
  1826. PUSH ACC
  1827. MOV R7,#03H
  1828. CLR A
  1829. IBD221 : MOV @R0,A
  1830. INC R0
  1831. DJNZ R7,IBD221
  1832. POP ACC
  1833. MOV R0,A
  1834. MOV R7,#10H
  1835. IBD222 : PUSH ACC
  1836. CLR C
  1837. MOV A,R4
  1838. RLC A
  1839. MOV R4,A
  1840. MOV A,R3
  1841. RLC A
  1842. MOV R3,A
  1843. MOV B,#03H
  1844. IBD223 : MOV A,@R0
  1845. ADDC A,@R0
  1846. DA A
  1847. MOV @R0,A
  1848. INC R0
  1849. DJNZ B,IBD223
  1850. POP ACC
  1851. MOV R0,A
  1852. DJNZ R7,IBD222
  1853. RET
  1854. ;二进制整数(3位)转换为十进制整数(分离BCD码)
  1855. ;入口: R2,R3,R4
  1856. ;占用资源: ACC,R2,NDIV31
  1857. ;堆栈需求: 5字节
  1858. ;出口: R0,NCNT
  1859. IBTD31 : CLR A
  1860. MOV NCNT,A
  1861. IBD311 : MOV R7,#0AH
  1862. LCALL NDIV31
  1863. MOV A,R7
  1864. MOV @R0,A
  1865. INC R0
  1866. INC NCNT
  1867. MOV A,R2
  1868. ORL A,R3
  1869. ORL A,R4
  1870. JNZ IBD311
  1871. MOV A,R0
  1872. CLR C
  1873. SUBB A,NCNT
  1874. MOV R0,A
  1875. RET
  1876. ;二进制整数(3位)转换为十进制整数(组合BCD码)
  1877. ;入口: R2,R3,R4
  1878. ;占用资源: ACC,B,R7
  1879. ;堆栈需求: 3字节
  1880. ;出口: R0
  1881. IBTD32 : MOV A,R0
  1882. PUSH ACC
  1883. MOV R7,#04H
  1884. CLR A
  1885. IBD321 : MOV @R0,A
  1886. INC R0
  1887. DJNZ R7,IBD321
  1888. POP ACC
  1889. MOV R0,A
  1890. MOV R7,#18H
  1891. IBD322 : PUSH ACC
  1892. CLR C
  1893. MOV A,R4
  1894. RLC A
  1895. MOV R4,A
  1896. MOV A,R3
  1897. RLC A
  1898. MOV R3,A
  1899. MOV A,R2
  1900. RLC A
  1901. MOV R2,A
  1902. MOV B,#04H
  1903. IBD323 : MOV A,@R0
  1904. ADDC A,@R0
  1905. DA A
  1906. MOV @R0,A
  1907. INC R0
  1908. DJNZ B,IBD323
  1909. POP ACC
  1910. MOV R0,A
  1911. DJNZ R7,IBD322
  1912. RET
  1913. ;二进制整数(M位)转换为十进制整数(组合BCD码)
  1914. ;入口: R1,M,N
  1915. ;占用资源: ACC,B,R2,R3,R7
  1916. ;堆栈需求: 2字节
  1917. ;出口: R0
  1918. IBTDMN : MOV A,R0
  1919. MOV R2,A
  1920. MOV A,R1
  1921. MOV R3,A
  1922. MOV B,N
  1923. CLR A
  1924. IBDMN1 : MOV @R0,A
  1925. INC R0
  1926. DJNZ B,IBDMN1
  1927. MOV A,M
  1928. SWAP A
  1929. RR A
  1930. CLR C
  1931. MOV R7,A
  1932. IBDMN2 : MOV A,R2
  1933. MOV R0,A
  1934. MOV A,R3
  1935. MOV R1,A
  1936. MOV B,M
  1937. IBDMN3 : MOV A,@R1
  1938. RLC A
  1939. MOV @R1,A
  1940. INC R1
  1941. DJNZ B,IBDMN3
  1942. MOV B,N
  1943. IBDMN4 : MOV A,@R0
  1944. ADDC A,@R0
  1945. DA A
  1946. JNB ACC.4,IBDMN5
  1947. SETB C
  1948. CLR ACC.4
  1949. IBDMN5 : MOV @R0,A
  1950. INC R0
  1951. DJNZ B,IBDMN4
  1952. DJNZ R7,IBDMN2
  1953. MOV A,R2
  1954. MOV R0,A
  1955. RET
  1956. ;(一) MCS-51定点运算子程序库及其使用说明
  1957. ;定点运算子程序库文件名为DQ51.ASM,为便于使用,先将有关约定说明如下:
  1958. ;1.多字节定点操作数:用[R0]或[R1]来表示存放在由R0或R1指示的连续单元中的数
  1959. ;据。地址小的单元存放数据的高字节。例如:[R0]=123456H,若(R0)=30H,则(30H)=12H,
  1960. ;(31H)=34H,(32H)=56H。
  1961. ;2.运算精度:单次定点运算精度为结果最低位的当量值。
  1962. ;3.工作区:数据工作区固定在PSW、A、B、R2~R7,用户只要不在工作区中存放无关的或非消耗性的信息,程序就具
  1963. ;有较好的透明性。
  1964. ;(1) 标号: BCDA 功能:多字节BCD码加法
  1965. ;入口条件:字节数在R7中,被加数在[R0]中,加数在[R1]中。
  1966. ;出口信息:和在[R0]中,最高位进位在CY中。
  1967. ;影响资源:PSW、A、R2 堆栈需求: 2字节
  1968. BCDA: MOV A,R7 ;取字节数至R2中
  1969. MOV R2,A
  1970. ADD A,R0 ;初始化数据指针
  1971. MOV R0,A
  1972. MOV A,R2
  1973. ADD A,R1
  1974. MOV R1,A
  1975. CLR C
  1976. BCD1: DEC R0 ;调整数据指针
  1977. DEC R1
  1978. MOV A,@R0
  1979. ADDC A,@R1 ;按字节相加
  1980. DA A ;十进制调整
  1981. MOV @R0,A ;和存回[R0]中
  1982. DJNZ R2,BCD1 ;处理完所有字节
  1983. RET
  1984. ;(2) 标号: BCDB 功能:多字节BCD码减法
  1985. ;入口条件:字节数在R7中,被减数在[R0]中,减数在[R1]中。
  1986. ;出口信息:差在[R0]中,最高位借位在CY中。
  1987. ;影响资源:PSW、A、R2、R3 堆栈需求: 6字节
  1988. BCDB: LCALL NEG1 ;减数[R1]十进制取补
  1989. LCALL BCDA ;按多字节BCD码加法处理
  1990. CPL C ;将补码加法的进位标志转换成借位标志
  1991. MOV F0,C ;保护借位标志
  1992. LCALL NEG1 ;恢复减数[R1]的原始值
  1993. MOV C,F0 ;恢复借位标志
  1994. RET
  1995. NEG1: MOV A,R0 ;[R1]十进制取补子程序入口
  1996. XCH A,R1 ;交换指针
  1997. XCH A,R0
  1998. LCALL NEG ;通过[R0]实现[R1]取补
  1999. MOV A,R0
  2000. XCH A,R1 ;换回指针
  2001. XCH A,R0
  2002. RET
  2003. ;(3) 标号: NEG 功能:多字节BCD码取补
  2004. ;入口条件:字节数在R7中,操作数在[R0]中。
  2005. ;出口信息:结果仍在[R0]中。
  2006. ;影响资源:PSW、A、R2、R3 堆栈需求: 2字节
  2007. NEG: MOV A,R7 ;取(字节数减一)至R2中
  2008. DEC A
  2009. MOV R2,A
  2010. MOV A,R0 ;保护指针
  2011. MOV R3,A
  2012. NEG0: CLR C
  2013. MOV A,#99H
  2014. SUBB A,@R0 ;按字节十进制取补
  2015. MOV @R0,A ;存回[R0]中
  2016. INC R0 ;调整数据指针
  2017. DJNZ R2,NEG0 ;处理完(R2)字节
  2018. MOV A,#9AH ;最低字节单独取补
  2019. SUBB A,@R0
  2020. MOV @R0,A
  2021. MOV A,R3 ;恢复指针
  2022. MOV R0,A
  2023. RET
  2024. ;(4) 标号: BRLN 功能:多字节BCD码左移十进制一位(乘十)
  2025. ;入口条件:字节数在R7中,操作数在[R0]中。
  2026. ;出口信息:结果仍在[R0]中,移出的十进制最高位在R3中。
  2027. ;影响资源:PSW、A、R2、R3 堆栈需求: 2字节
  2028. BRLN: MOV A,R7 ;取字节数至R2中
  2029. MOV R2,A
  2030. ADD A,R0 ;初始化数据指针
  2031. MOV R0,A
  2032. MOV R3,#0 ;工作单元初始化
  2033. BRL1: DEC R0 ;调整数据指针
  2034. MOV A,@R0 ;取一字节
  2035. SWAP A ;交换十进制高低位
  2036. MOV @R0,A ;存回
  2037. MOV A,R3 ;取低字节移出的十进制高位
  2038. XCHD A,@R0 ;换出本字节的十进制高位
  2039. MOV R3,A ;保存本字节的十进制高位
  2040. DJNZ R2,BRL1 ;处理完所有字节
  2041. RET
  2042. ;(5) 标号: MULD 功能:双字节二进制无符号数乘法
  2043. ;入口条件:被乘数在R2、R3中,乘数在R6、R7中。
  2044. ;出口信息:乘积在R2、R3、R4、R5中。
  2045. ;影响资源:PSW、A、B、R2~R7 堆栈需求: 2字节
  2046. MULD: MOV A,R3 ;计算R3乘R7
  2047. MOV B,R7
  2048. MUL AB
  2049. MOV R4,B ;暂存部分积
  2050. MOV R5,A
  2051. MOV A,R3 ;计算R3乘R6
  2052. MOV B,R6
  2053. MUL AB
  2054. ADD A,R4 ;累加部分积
  2055. MOV R4,A
  2056. CLR A
  2057. ADDC A,B
  2058. MOV R3,A
  2059. MOV A,R2 ;计算R2乘R7
  2060. MOV B,R7
  2061. MUL AB
  2062. ADD A,R4 ;累加部分积
  2063. MOV R4,A
  2064. MOV A,R3
  2065. ADDC A,B
  2066. MOV R3,A
  2067. CLR A
  2068. RLC A
  2069. XCH A,R2 ;计算R2乘R6
  2070. MOV B,R6
  2071. MUL AB
  2072. ADD A,R3 ;累加部分积
  2073. MOV R3,A
  2074. MOV A,R2
  2075. ADDC A,B
  2076. MOV R2,A
  2077. RET
  2078. ;(6) 标号: MUL2 功能:双字节二进制无符号数平方
  2079. ;入口条件:待平方数在R2、R3中。
  2080. ;出口信息:结果在R2、R3、R4、R5中。
  2081. ;影响资源:PSW、A、B、R2~R5 堆栈需求: 2字节
  2082. MUL2: MOV A,R3 ;计算R3平方
  2083. MOV B,A
  2084. MUL AB
  2085. MOV R4,B ;暂存部分积
  2086. MOV R5,A
  2087. MOV A,R2 ;计算R2平方
  2088. MOV B,A
  2089. MUL AB
  2090. XCH A,R3 ;暂存部分积,并换出R2和R3
  2091. XCH A,B
  2092. XCH A,R2
  2093. MUL AB ;计算2×R2×R3
  2094. CLR C
  2095. RLC A
  2096. XCH A,B
  2097. RLC A
  2098. JNC MU20
  2099. INC R2 ;累加溢出量
  2100. MU20: XCH A,B ;累加部分积
  2101. ADD A,R4
  2102. MOV R4,A
  2103. MOV A,R3
  2104. ADDC A,B
  2105. MOV R3,A
  2106. CLR A
  2107. ADDC A,R2
  2108. MOV R2,A
  2109. RET
  2110. ;(7) 标号: DIVD 功能:双字节二进制无符号数除法
  2111. ;入口条件:被除数在R2、R3、R4、R5中,除数在R6、R7中。
  2112. ;出口信息:OV=0 时,双字节商在R2、R3中,OV=1 时溢出。
  2113. ;影响资源:PSW、A、B、R1~R7 堆栈需求: 2字节
  2114. DIVD: CLR C ;比较被除数和除数
  2115. MOV A,R3
  2116. SUBB A,R7
  2117. MOV A,R2
  2118. SUBB A,R6
  2119. JC DVD1
  2120. SETB OV ;溢出
  2121. RET
  2122. DVD1: MOV B,#10H ;计算双字节商
  2123. DVD2: CLR C ;部分商和余数同时左移一位
  2124. MOV A,R5
  2125. RLC A
  2126. MOV R5,A
  2127. MOV A,R4
  2128. RLC A
  2129. MOV R4,A
  2130. MOV A,R3
  2131. RLC A
  2132. MOV R3,A
  2133. XCH A,R2
  2134. RLC A
  2135. XCH A,R2
  2136. MOV F0,C ;保存溢出位
  2137. CLR C
  2138. SUBB A,R7 ;计算(R2R3-R6R7)
  2139. MOV R1,A
  2140. MOV A,R2
  2141. SUBB A,R6
  2142. ANL C,/F0 ;结果判断
  2143. JC DVD3
  2144. MOV R2,A ;够减,存放新的余数
  2145. MOV A,R1
  2146. MOV R3,A
  2147. INC R5 ;商的低位置一
  2148. DVD3: DJNZ B,DVD2 ;计算完十六位商(R4R5)
  2149. MOV A,R4 ;将商移到R2R3中
  2150. MOV R2,A
  2151. MOV A,R5
  2152. MOV R3,A
  2153. CLR OV ;设立成功标志
  2154. RET
  2155. ;(8) 标号: D457 功能:双字节二进制无符号数除以单字节二进制数
  2156. ;入口条件:被除数在R4、R5中,除数在R7中。
  2157. ;出口信息:OV=0 时,单字节商在R3中,OV=1 时溢出。
  2158. ;影响资源:PSW、A、R3~R7 堆栈需求: 2字节
  2159. D457: CLR C
  2160. MOV A,R4
  2161. SUBB A,R7
  2162. JC DV50
  2163. SETB OV ;商溢出
  2164. RET
  2165. DV50: MOV R6,#8 ;求平均值(R4R5/R7-→R3)
  2166. DV51: MOV A,R5
  2167. RLC A
  2168. MOV R5,A
  2169. MOV A,R4
  2170. RLC A
  2171. MOV R4,A
  2172. MOV F0,C
  2173. CLR C
  2174. SUBB A,R7
  2175. ANL C,/F0
  2176. JC DV52
  2177. MOV R4,A
  2178. DV52: CPL C
  2179. MOV A,R3
  2180. RLC A
  2181. MOV R3,A
  2182. DJNZ R6,DV51
  2183. MOV A,R4 ;四舍五入
  2184. ADD A,R4
  2185. JC DV53
  2186. SUBB A,R7
  2187. JC DV54
  2188. DV53: INC R3
  2189. DV54: CLR OV
  2190. RET
  2191. ;(9) 标号: DV31 功能:三字节二进制无符号数除以单字节二进制数
  2192. ;入口条件:被除数在R3、R4、R5中,除数在R7中。
  2193. ;出口信息:OV=0 时,双字节商在R4、R5中,OV=1 时溢出。
  2194. ;影响资源:PSW、A、B、R2~R7 堆栈需求: 2字节
  2195. DV31: CLR C
  2196. MOV A,R3
  2197. SUBB A,R7
  2198. JC DV30
  2199. SETB OV ;商溢出
  2200. RET
  2201. DV30: MOV R2,#10H ;求R3R4R5/R7-→R4R5
  2202. DM23: CLR C
  2203. MOV A,R5
  2204. RLC A
  2205. MOV R5,A
  2206. MOV A,R4
  2207. RLC A
  2208. MOV R4,A
  2209. MOV A,R3
  2210. RLC A
  2211. MOV R3,A
  2212. MOV F0,C
  2213. CLR C
  2214. SUBB A,R7
  2215. ANL C,/F0
  2216. JC DM24
  2217. MOV R3,A
  2218. INC R5
  2219. DM24: DJNZ R2,DM23
  2220. MOV A,R3 ;四舍五入
  2221. ADD A,R3
  2222. JC DM25
  2223. SUBB A,R7
  2224. JC DM26
  2225. DM25: INC R5
  2226. MOV A,R5
  2227. JNZ DM26
  2228. INC R4
  2229. DM26: CLR OV
  2230. RET ;商在R4R5中
  2231. ;(10) 标号: MULS 功能:双字节二进制有符号数乘法(补码)
  2232. ;入口条件:被乘数在R2、R3中,乘数在R6、R7中。
  2233. ;出口信息:乘积在R2、R3、R4、R5中。
  2234. ;影响资源:PSW、A、B、R2~R7 堆栈需求: 4字节
  2235. MULS: MOV R4,#0 ;清零R4R5
  2236. MOV R5,#0
  2237. LCALL MDS ;计算结果的符号和两个操作数的绝对值
  2238. LCALL MULD ;计算两个绝对值的乘积
  2239. SJMP MDSE ;用补码表示结果
  2240. ;(11) 标号: DIVS 功能:双字节二进制有符号数除法(补码)
  2241. ;入口条件:被除数在R2、R3、R4、R5中,除数在R6、R7中。
  2242. ;出口信息:OV=0时商在R2、R3中,OV=1时溢出。
  2243. ;影响资源:PSW、A、B、R1~R7 堆栈需求: 5字节
  2244. DIVS: LCALL MDS ;计算结果的符号和两个操作数的绝对值
  2245. PUSH PSW ;保存结果的符号
  2246. LCALL DIVD ;计算两个绝对值的商
  2247. JNB OV,DVS1 ;溢出否?
  2248. POP ACC ;溢出,放去结果的符号,保留溢出标志
  2249. RET
  2250. DVS1: POP PSW ;未溢出,取出结果的符号
  2251. MOV R4,#0
  2252. MOV R5,#0
  2253. MDSE: JB F0,MDS2 ;用补码表示结果
  2254. CLR OV ;结果为正,原码即补码,计算成功
  2255. RET
  2256. MDS: CLR F0 ;结果符号初始化
  2257. MOV A,R6 ;判断第二操作数的符号
  2258. JNB ACC.7,MDS1;为正,不必处理
  2259. CPL F0 ;为负,结果符号取反
  2260. XCH A,R7 ;第二操作数取补,得到其绝对值
  2261. CPL A
  2262. ADD A,#1
  2263. XCH A,R7
  2264. CPL A
  2265. ADDC A,#0
  2266. MOV R6,A
  2267. MDS1: MOV A,R2 ;判断第一操作数或运算结果的符号
  2268. JNB ACC.7,MDS3;为正,不必处理
  2269. CPL F0 ;为负,结果符号取反
  2270. MDS2: MOV A,R5 ;求第一操作数的绝对值或运算结果的补码
  2271. CPL A
  2272. ADD A,#1
  2273. MOV R5,A
  2274. MOV A,R4
  2275. CPL A
  2276. ADDC A,#0
  2277. MOV R4,A
  2278. MOV A,R3
  2279. CPL A
  2280. ADDC A,#0
  2281. MOV R3,A
  2282. MOV A,R2
  2283. CPL A
  2284. ADDC A,#0
  2285. MOV R2,A
  2286. MDS3: CLR OV ;运算成功
  2287. RET
  2288. ;(12) 标号: SH2 功能:双字节二进制无符号数开平方(快速)
  2289. ;入口条件:被开方数在R2、R3中。
  2290. ;出口信息:平方根仍在R2、R3中,整数部分的位数为原数的一半,其余为小数。
  2291. ;影响资源:PSW、A、B、R2~R7 堆栈需求: 2字节
  2292. SH2: MOV A,R2
  2293. ORL A,R3
  2294. JNZ SH20
  2295. RET ;被开方数为零,不必运算
  2296. SH20: MOV R7,#0 ;左规次数初始化
  2297. MOV A,R2
  2298. SH22: ANL A,#0C0H ;被开方数高字节小于40H否?
  2299. JNZ SQRH ;不小于40H,左规格化完成,转开方过程
  2300. CLR C ;每左规一次,被开方数左移两位
  2301. MOV A,R3
  2302. RLC A
  2303. MOV F0,C
  2304. CLR C
  2305. RLC A
  2306. MOV R3,A
  2307. MOV A,R2
  2308. MOV ACC.7,C
  2309. MOV C,F0
  2310. RLC A
  2311. RLC A
  2312. MOV R2,A
  2313. INC R7 ;左规次数加一
  2314. SJMP SH22 ;继续左规
  2315. ;(13) 标号: SH4 功能:四字节二进制无符号数开平方(快速)
  2316. ;口条件:被开方数在R2、R3、R4、R5中。
  2317. ;出口信息:平方根在R2、R3中,整数部分的位数为原数的一半,其余为小数。
  2318. ;影响资源:PSW、A、B、R2~R7 堆栈需求: 2字节
  2319. SH4: MOV A,R2
  2320. ORL A,R3
  2321. ORL A,R4
  2322. ORL A,R5
  2323. JNZ SH40
  2324. RET ;被开方数为零,不必运算
  2325. SH40: MOV R7,#0 ;左规次数初始化
  2326. MOV A,R2
  2327. SH41: ANL A,#0C0H ;被开方数高字节小于40H否?
  2328. JNZ SQRH ;不小于40H,左规格化完成
  2329. MOV R6,#2 ;每左规一次,被开方数左移两位
  2330. SH42: CLR C ;被开方数左移一位
  2331. MOV A,R5
  2332. RLC A
  2333. MOV R5,A
  2334. RLC A
  2335. MOV R4,A
  2336. MOV A,R3
  2337. RLC A
  2338. MOV R3,A
  2339. MOV A,R2
  2340. RLC A
  2341. MOV R2,A
  2342. DJNZ R6,SH42 ;被开方数左移完两位
  2343. INC R7 ;左规次数加一
  2344. SJMP SH41 ;继续左规
  2345. SQRH: MOV A,R2 ;规格化后高字节按折线法分为三个区间
  2346. ADD A,#57H
  2347. JC SQR2
  2348. ADD A,#45H
  2349. JC SQR1
  2350. ADD A,#24H
  2351. MOV B,#0E3H ;第一区间的斜率
  2352. MOV R4,#80H ;第一区间的平方根基数
  2353. SJMP SQR3
  2354. SQR1: MOV B,#0B2H ;第二区间的斜率
  2355. MOV R4,#0A0H;第二区间的平方根基数
  2356. SJMP SQR3
  2357. SQR2: MOV B,#8DH ;第三区间的斜率
  2358. MOV R4,#0D0H;第三区间的平方根基数
  2359. SQR3: MUL AB ;与区间基点的偏移量乘区间斜率
  2360. MOV A,B
  2361. ADD A,R4 ;累加到平方根的基数上
  2362. MOV R4,A
  2363. MOV B,A
  2364. MUL AB ;求当前平方根的幂
  2365. XCH A,R3 ;求偏移量(存放在R2R3中)
  2366. CLR C
  2367. SUBB A,R3
  2368. MOV R3,A
  2369. MOV A,R2
  2370. SUBB A,B
  2371. MOV R2,A
  2372. SQR4: SETB C ;用减奇数法校正一个字节的平方根
  2373. MOV A,R4 ;当前平方根的两倍加一存入R5R6中
  2374. RLC A
  2375. MOV R6,A
  2376. CLR A
  2377. RLC A
  2378. MOV R5,A
  2379. MOV A,R3 ;偏移量小于该奇数否?
  2380. SUBB A,R6
  2381. MOV B,A
  2382. MOV A,R2
  2383. SUBB A,R5
  2384. JC SQR5 ;小于,校正结束,已达到一个字节的精度
  2385. INC R4 ;不小于,平方根加一
  2386. MOV R2,A ;保存新的偏移量
  2387. MOV R3,B
  2388. SJMP SQR4 ;继续校正
  2389. SQR5: MOV A,R4 ;将一个字节精度的根存入R2
  2390. XCH A,R2
  2391. RRC A
  2392. MOV F0,C ;保存最终偏移量的最高位
  2393. MOV A,R3
  2394. MOV R5,A ;将最终偏移量的低八位存入R5中
  2395. MOV R4,#8 ;通过(R5R6/R2)求根的低字节
  2396. SQR6: CLR C
  2397. MOV A,R3
  2398. RLC A
  2399. MOV R3,A
  2400. CLR C
  2401. MOV A,R5
  2402. SUBB A,R2
  2403. JB F0,SQR7
  2404. JC SQR8
  2405. SQR7: MOV R5,A
  2406. INC R3
  2407. SQR8: CLR C
  2408. MOV A,R5
  2409. RLC A
  2410. MOV R5,A
  2411. MOV F0,C
  2412. DJNZ R4,SQR6 ;根的第二字节计算完,在R3中
  2413. MOV A,R7 ;取原被开方数的左规次数
  2414. JZ SQRE ;未左规,开方结束
  2415. SQR9: CLR C ;按左规次数右移平方根,得到实际根
  2416. MOV A,R2
  2417. RRC A
  2418. MOV R2,A
  2419. MOV A,R3
  2420. RRC A
  2421. MOV R3,A
  2422. DJNZ R7,SQR9
  2423. SQRE: RET
  2424. ;(14) 标号: HASC 功能:单字节十六进制数转换成双字节ASCII码
  2425. ;入口条件:待转换的单字节十六进制数在累加器A中。
  2426. ;出口信息:高四位的ASCII码在A中,低四位的ASCII码在B中。
  2427. ;影响资源:PSW、A、B 堆栈需求: 4字节
  2428. HASC: MOV B,A ;暂存待转换的单字节十六进制数
  2429. LCALL HAS1 ;转换低四位
  2430. XCH A,B ;存放低四位的ASCII码
  2431. SWAP A ;准备转换高四位
  2432. HAS1: ANL A,#0FH ;将累加器的低四位转换成ASCII码
  2433. ADD A,#90H
  2434. DA A
  2435. ADDC A,#40H
  2436. DA A
  2437. RET
  2438. ;(15) 标号: ASCH 功能:ASCII码转换成十六进制数
  2439. ;入口条件:待转换的ASCII码(30H~39H或41H~46H)在A中。
  2440. ;出口信息:转换后的十六进制数(00H~0FH)仍在累加器A中。
  2441. ;影响资源:PSW、A 堆栈需求: 2字节
  2442. ASCH: CLR C
  2443. SUBB A,#30H
  2444. JNB ACC.4,ASH1
  2445. SUBB A,#7
  2446. ASH1: RET
  2447. ;(16) 标号:HBCD 功能:单字节十六进制整数转换成单字节BCD码整数
  2448. ;入口条件:待转换的单字节十六进制整数在累加器A中。
  2449. ;出口信息:转换后的BCD码整数(十位和个位)仍在累加器A中,百位在R3中。
  2450. ;影响资源:PSW、A、B、R3 堆栈需求: 2字节
  2451. HBCD: MOV B,#100 ;分离出百位,存放在R3中
  2452. DIV AB
  2453. MOV R3,A
  2454. MOV A,#10 ;余数继续分离十位和个位
  2455. XCH A,B
  2456. DIV AB
  2457. SWAP A
  2458. ORL A,B ;将十位和个位拼装成BCD码
  2459. RET
  2460. ;(17) 标号: HB2 功能:双字节十六进制整数转换成双字节BCD码整数
  2461. ;入口条件:待转换的双字节十六进制整数在R6、R7中。
  2462. ;出口信息:转换后的三字节BCD码整数在R3、R4、R5中。
  2463. ;影响资源:PSW、A、R2~R7 堆栈需求: 2字节
  2464. HB2: CLR A ;BCD码初始化
  2465. MOV R3,A
  2466. MOV R4,A
  2467. MOV R5,A
  2468. MOV R2,#10H ;转换双字节十六进制整数
  2469. HB3: MOV A,R7 ;从高端移出待转换数的一位到CY中
  2470. RLC A
  2471. MOV R7,A
  2472. MOV A,R6
  2473. RLC A
  2474. MOV R6,A
  2475. MOV A,R5 ;BCD码带进位自身相加,相当于乘2
  2476. ADDC A,R5
  2477. DA A ;十进制调整
  2478. MOV R5,A
  2479. MOV A,R4
  2480. ADDC A,R4
  2481. DA A
  2482. MOV R4,A
  2483. MOV A,R3
  2484. ADDC A,R3
  2485. MOV R3,A ;双字节十六进制数的万位数不超过6,不用调整
  2486. DJNZ R2,HB3 ;处理完16bit
  2487. RET
  2488. ;(18) 标号: HBD 功能:单字节十六进制小数转换成单字节BCD码小数
  2489. ;入口条件:待转换的单字节十六进制小数在累加器A中。
  2490. ;出口信息:CY=0时转换后的BCD码小数仍在A中。CY=1时原小数接近整数1。
  2491. ;影响资源:PSW、A、B 堆栈需求: 2字节
  2492. HBD: MOV B,#100 ;原小数扩大一百倍
  2493. MUL AB
  2494. RLC A ;余数部分四舍五入
  2495. CLR A
  2496. ADDC A,B
  2497. MOV B,#10 ;分离出十分位和百分位
  2498. DIV AB
  2499. SWAP A
  2500. ADD A,B ;拼装成单字节BCD码小数
  2501. DA A ;调整后若有进位,原小数接近整数1
  2502. RET
  2503. ;(19) 标号: HBD2 功能:双字节十六进制小数转换成双字节BCD码小数
  2504. ;入口条件:待转换的双字节十六进制小数在R2、R3中。
  2505. ;出口信息:转换后的双字节BCD码小数仍在R2、R3中。
  2506. ;影响资源:PSW、A、B、R2、R3、R4、R5 堆栈需求: 6字节
  2507. HBD2: MOV R4,#4 ;四位十进制码
  2508. HBD3: MOV A,R3 ;原小数扩大十倍
  2509. MOV B,#10
  2510. MUL AB
  2511. MOV R3,A
  2512. MOV R5,B
  2513. MOV A,R2
  2514. MOV B,#10
  2515. MUL AB
  2516. ADD A,R5
  2517. MOV R2,A
  2518. CLR A
  2519. ADDC A,B
  2520. PUSH ACC ;保存溢出的一位十进制码
  2521. DJNZ R4,HBD3 ;计算完四位十进制码
  2522. POP ACC ;取出万分位
  2523. MOV R3,A
  2524. POP ACC ;取出千分位
  2525. SWAP A
  2526. ORL A,R3 ;拼装成低字节BCD码小数
  2527. MOV R3,A
  2528. POP ACC ;取出百分位
  2529. MOV R2,A
  2530. POP ACC ;取出十分位
  2531. SWAP A
  2532. ORL A,R2 ;拼装成高字节BCD码小数
  2533. MOV R2,A
  2534. RET
  2535. ;(20)标号:BCDH 功能:单字节BCD码整数转换成单字节十六进制整数
  2536. ;入口条件:待转换的单字节BCD码整数在累加器A中。
  2537. ;出口信息:转换后的单字节十六进制整数仍在累加器A中。
  2538. ;影响资源:PSW、A、B、R4 堆栈需求: 2字节
  2539. BCDH: MOV B,#10H ;分离十位和个位
  2540. DIV AB
  2541. MOV R4,B ;暂存个位
  2542. MOV B,#10 ;将十位转换成十六进制
  2543. MUL AB
  2544. ADD A,R4 ;按十六进制加上个位
  2545. RET
  2546. ;(21)标号: BH2 功能:双字节BCD码整数转换成双字节十六进制整数
  2547. ;入口条件:待转换的双字节BCD码整数在R2、R3中。
  2548. ;出口信息:转换后的双字节十六进制整数仍在R2、R3中。
  2549. ;影响资源:PSW、A、B、R2、R3、R4 堆栈需求: 4字节
  2550. BH2: MOV A,R3 ;将低字节转换成十六进制
  2551. LCALL BCDH
  2552. MOV R3,A
  2553. MOV A,R2 ;将高字节转换成十六进制
  2554. LCALL BCDH
  2555. MOV B,#100 ;扩大一百倍
  2556. MUL AB
  2557. ADD A,R3 ;和低字节按十六进制相加
  2558. MOV R3,A
  2559. CLR A
  2560. ADDC A,B
  2561. MOV R2,A
  2562. RET
  2563. ;(22)标号: BHD 功能:单字节BCD码小数转换成单字节十六进制小数
  2564. ;入口条件:待转换的单字节BCD码数在累加器A中。
  2565. ;出口信息:转换后的单字节十六进制小数仍在累加器A中。
  2566. ;影响资源:PSW、A、R2、R3 堆栈需求: 2字节
  2567. BHD: MOV R2,#8 ;准备计算一个字节小数
  2568. BHD0: ADD A,ACC ;按十进制倍增
  2569. DA A
  2570. XCH A,R3
  2571. RLC A ;将进位标志移入结果中
  2572. XCH A,R3
  2573. DJNZ R2,BHD0 ;共计算8bit小数
  2574. ADD A,#0B0H ;剩余部分达到0.50否?
  2575. JNC BHD1 ;四舍
  2576. INC R3 ;五入
  2577. BHD1: MOV A,R3 ;取结果
  2578. RET
  2579. ;(23)标号: BHD2 功能:双字节BCD码小数转换成双字节十六进制小数
  2580. ;入口条件:待转换的双字节BCD码小数在R4、R5中。
  2581. ;出口信息:转换后的双字节十六进制小数在R2、R3中。
  2582. ;影响资源:PSW、A、R2~R6 堆栈需求: 2字节
  2583. BHD2: MOV R6,#10H ;准备计算两个字节小数
  2584. BHD3: MOV A,R5 ;按十进制倍增
  2585. ADD A,R5
  2586. DA A
  2587. MOV R5,A
  2588. MOV A,R4
  2589. ADDC A,R4
  2590. DA A
  2591. MOV R4,A
  2592. MOV A,R3 ;将进位标志移入结果中
  2593. RLC A
  2594. MOV R3,A
  2595. MOV A,R2
  2596. RLC A
  2597. MOV R2,A
  2598. DJNZ R6,BHD3 ;共计算16bit小数
  2599. MOV A,R4
  2600. ADD A,#0B0H ;剩余部分达到0.50否?
  2601. JNC BHD4 ;四舍
  2602. INC R3 ;五入
  2603. MOV A,R3
  2604. JNZ BHD4
  2605. INC R2
  2606. BHD4: RET
  2607. ;(24) 标号: MM 功能:求单字节十六进制无符号数据块的极值
  2608. ;入口条件:数据块的首址在DPTR中,数据个数在R7中。
  2609. ;出口信息:最大值在R6中,地址在R2R3中;最小值在R7中,地址在R4R5中。
  2610. ;影响资源:PSW、A、B、R1~R7 堆栈需求: 4字节
  2611. MM: MOV B,R7 ;保存数据个数
  2612. MOVX A,@DPTR ;读取第一个数据
  2613. MOV R6,A ;作为最大值的初始值
  2614. MOV R7,A ;也作为最小值的初始值
  2615. MOV A,DPL ;取第一个数据的地址
  2616. MOV R3,A ;作为最大值存放地址的初始值
  2617. MOV R5,A ;也作为最小值存放地址的初始值
  2618. MOV A,DPH
  2619. MOV R2,A
  2620. MOV R4,A
  2621. MOV A,B ;取数据个数
  2622. DEC A ;减一,得到需要比较的次数
  2623. JZ MME ;只有一个数据,不需要比较
  2624. MOV R1,A ;保存比较次数
  2625. PUSH DPL ;保护数据块的首址
  2626. PUSH DPH
  2627. MM1: INC DPTR ;指向一个新的数据
  2628. MOVX A,@DPTR ;读取这个数据
  2629. MOV B,A ;保存
  2630. SETB C ;与最大值比较
  2631. SUBB A,R6
  2632. JC MM2 ;不超过当前最大值,保持当前最大值
  2633. MOV R6,B ;超过当前最大值,更新最大值存放地址
  2634. MOV R2,DPH ;同时更新最大值存放地址
  2635. MOV R3,DPL
  2636. SJMP MM3
  2637. MM2: MOV A,B ;与最小值比较
  2638. CLR C
  2639. SUBB A,R7
  2640. JNC MM3 ;大于或等于当前最小值,保持当前最小值
  2641. MOV R7,B ;更新最小值
  2642. MOV R4,DPH ;更新最小值存放地址
  2643. MOV R5,DPL
  2644. MM3: DJNZ R1,MM1 ;处理完全部数据
  2645. POP DPH ;恢复数据首址
  2646. POP DPL
  2647. MME: RET
  2648. ;(25) 标号: MMS 功能:求单字节十六进制有符号数据块的极值
  2649. ;入口条件:数据块的首址在DPTR中,数据个数在R7中。
  2650. ;出口信息:最大值在R6中, 地址在R2R3中;最小值在R7中,地址在R4R5中。
  2651. ;影响资源:PSW、A、B、R1~R7 堆栈需求: 4字节
  2652. MMS: MOV B,R7 ;保存数据个数
  2653. MOVX A,@DPTR ;读取第一个数据
  2654. MOV R6,A ;作为最大值的初始值
  2655. MOV R7,A ;也作为最小值的初始值
  2656. MOV A,DPL ;取第一个数据的地址
  2657. MOV R3,A ;作为最大值存放地址的初始值
  2658. MOV R5,A ;也作为最小值存放地址的初始值
  2659. MOV A,DPH
  2660. MOV R2,A
  2661. MOV R4,A
  2662. MOV A,B ;取数据个数
  2663. DEC A ;减一,得到需要比较的次数
  2664. JZ MMSE ;只有一个数据,不需要比较
  2665. MOV R1,A ;保存比较次数
  2666. PUSH DPL ;保护数据块的首址
  2667. PUSH DPH
  2668. MMS1: INC DPTR ;调整数据指针
  2669. MOVX A,@DPTR ;读取一个数据
  2670. MOV B,A ;保存
  2671. SETB C ;与最大值比较
  2672. SUBB A,R6
  2673. JZ MMS4 ;相同,不更新最大值
  2674. JNB OV,MMS2 ;差未溢出,符号位有效
  2675. CPL ACC.7 ;差溢出,符号位取反
  2676. MMS2: JB ACC.7,MMS4;差为负,不更新最大值
  2677. MOV R6,B ;更新最大值
  2678. MOV R2,DPH ;更新最大值存放地址
  2679. MOV R3,DPL
  2680. SJMP MMS7
  2681. MMS4: MOV A,B ;与最小值比较
  2682. CLR C
  2683. SUBB A,R7
  2684. JNB OV,MMS6 ;差未溢出,符号位有效
  2685. CPL ACC.7 ;差溢出,符号位取反
  2686. MMS6: JNB ACC.7,MMS7;差为正,不更新最小值
  2687. MOV R7,B ;更新最小值
  2688. MOV R4,DPH ;更新最小值存放地址
  2689. MOV R5,DPL
  2690. MMS7: DJNZ R1,MMS1 ;处理完全部数据
  2691. POP DPH ;恢复数据首址
  2692. POP DPL
  2693. MMSE: RET
  2694. ;(26) 标号: FDS1 功能:顺序查找(ROM)单字节表格
  2695. ;入口条件:待查找的内容在A中,表格首址在DPTR中,表格的字节数在R7中。
  2696. ;出口信息:OV=0时,顺序号在累加器A中;OV=1时,未找到。
  2697. ;影响资源:PSW、A、B、R2、R6 堆栈需求: 2字节
  2698. FDS1: MOV B,A ;保存待查找的内容
  2699. MOV R2,#0 ;顺序号初始化(指向表首)
  2700. MOV A,R7 ;保存表格的长度
  2701. MOV R6,A
  2702. FD11: MOV A,R2 ;按顺序号读取表格内容
  2703. MOVC A,@A+DPTR
  2704. CJNE A,B,FD12;与待查找的内容比较
  2705. CLR OV ;相同,查找成功
  2706. MOV A,R2 ;取对应的顺序号
  2707. RET
  2708. FD12: INC R2 ;指向表格中的下一个内容
  2709. DJNZ R6,FD11 ;查完全部表格内容
  2710. SETB OV ;未查找到,失败
  2711. RET
  2712. ;(27) 标号: FDS2 功能:顺序查找(ROM)双字节表格
  2713. ;入口条件:查找内容在R4、R5中,表格首址在DPTR中,数据总个数在R7中。
  2714. ;出口信息:OV=0时顺序号在累加器A中,地址在DPTR中;OV=1时未找到。
  2715. ;影响资源:PSW、A、R2、R6、DPTR 堆栈需求: 2字节
  2716. FDS2: MOV A,R7 ;保存表格中数据的个数
  2717. MOV R6,A
  2718. MOV R2,#0 ;顺序号初始化(指向表首)
  2719. FD21: CLR A ;读取表格内容的高字节
  2720. MOVC A,@A+DPTR
  2721. XRL A,R4 ;与待查找内容的高字节比较
  2722. JNZ FD22
  2723. MOV A,#1 ;读取表格内容的低字节
  2724. MOVC A,@A+DPTR
  2725. XRL A,R5 ;与待查找内容的低字节比较
  2726. JNZ FD22
  2727. CLR OV ;相同,查找成功
  2728. MOV A,R2 ;取对应的顺序号
  2729. RET
  2730. FD22: INC DPTR ;指向下一个数据
  2731. INC DPTR
  2732. INC R2 ;顺序号加一
  2733. DJNZ R6,FD21 ;查完全部数据
  2734. SETB OV ;未查找到,失败
  2735. RET
  2736. ;(28) 标号:FDD1 功能:对分查找(ROM)单字节无符号增序数据表格
  2737. ;入口条件:待查找的内容在累加器A中,表格首址在DPTR中,字节数在R7中。
  2738. ;出口信息:OV=0 时,顺序号在累加器A中;OV=1 时,未找到。
  2739. ;影响资源:PSW、A、B、R2、R3、R4 堆栈需求: 2字节
  2740. FDD1: MOV B,A ;保存待查找的内容
  2741. MOV R2,#0 ;区间低端指针初始化(指向第一个数据)
  2742. MOV A,R7
  2743. DEC A
  2744. MOV R3,A ;区间高端指针初始化(指向最后一个数据)
  2745. FD61: CLR C ;判断区间大小
  2746. MOV A,R3
  2747. SUBB A,R2
  2748. JC FD69 ;区间消失,查找失败
  2749. RRC A ;取区间大小的一半
  2750. ADD A,R2 ;加上区间的低端
  2751. MOV R4,A ;得到区间的中心
  2752. MOVC A,@A+DPTR;读取该点的内容
  2753. CJNE A,B,FD65;与待查找的内容比较
  2754. CLR OV ;相同,查找成功
  2755. MOV A,R4 ;取顺序号
  2756. RET
  2757. FD65: JC FD68 ;该点的内容比待查找的内容大否?
  2758. MOV A,R4 ;偏大,取该点位置
  2759. DEC A ;减一
  2760. MOV R3,A ;作为新的区间高端
  2761. SJMP FD61 ;继续查找
  2762. FD68: MOV A,R4 ;偏小,取该点位置
  2763. INC A ;加一
  2764. MOV R2,A ;作为新的区间低端
  2765. SJMP FD61 ;继续查找
  2766. FD69: SETB OV ;查找失败
  2767. RET
  2768. ;(29) 标号:FDD2 功能:对分查找(ROM)双字节无符号增序数据表格
  2769. ;入口条件:查找内容在R4、R5中,表格首址在DPTR中,数据个数在R7中。
  2770. ;出口信息:OV=0 时顺序号在累加器A中,址在DPTR中;OV=1 时未找到。
  2771. ;影响资源:PSW、A、B、R1~R7、DPTR 堆栈需求: 2字节
  2772. FDD2: MOV R2,#0 ;区间低端指针初始化(指向第一个数据)
  2773. MOV A,R7
  2774. DEC A
  2775. MOV R3,A ;区间高端指针初始化,指向最后一个数据
  2776. MOV R6,DPH ;保存表格首址
  2777. MOV R7,DPL
  2778. FD81: CLR C ;判断区间大小
  2779. MOV A,R3
  2780. SUBB A,R2
  2781. JC FD89 ;区间消失,查找失败
  2782. RRC A ;取区间大小的一半
  2783. ADD A,R2 ;加上区间的低端
  2784. MOV R1,A ;得到区间的中心
  2785. MOV DPH,R6
  2786. CLR C ;计算区间中心的地址
  2787. RLC A
  2788. JNC FD82
  2789. INC DPH
  2790. FD82: ADD A,R7
  2791. MOV DPL,A
  2792. JNC FD83
  2793. INC DPH
  2794. FD83: CLR A ;读取该点的内容的高字节
  2795. MOVC A,@A+DPTR
  2796. MOV B,R4 ;与待查找内容的高字节比较
  2797. CJNE A,B,FD84;不相同
  2798. MOV A,#1 ;读取该点的内容的低字节
  2799. MOVC A,@A+DPTR
  2800. MOV B,R5
  2801. CJNE A,B,FD84;与待查找内容的低字节比较
  2802. MOV A,R1 ;取顺序号
  2803. CLR OV ;查找成功
  2804. RET
  2805. FD84: JC FD86 ;该点的内容比待查找的内容大否?
  2806. MOV A,R1 ;偏大,取该点位置
  2807. DEC A ;减一
  2808. MOV R3,A ;作为新的区间高端
  2809. SJMP FD81 ;继续查找
  2810. FD86: MOV A,R1 ;偏小,取该点位置
  2811. INC A ;加一
  2812. MOV R2,A ;作为新的区间低端
  2813. SJMP FD81 ;继续查找
  2814. FD89: MOV DPH,R6 ;相同,恢复首址
  2815. MOV DPL,R7
  2816. SETB OV ;查找失败
  2817. RET
  2818. ;(30) 标号: DDM1 功能:求单字节十六进制无符号数据块的平均值
  2819. ;入口条件:数据块的首址在DPTR中,数据个数在R7中。
  2820. ;出口信息:平均值在累加器A中。
  2821. ;影响资源:PSW、A、R2~R6 堆栈需求: 4字节
  2822. DDM1: MOV A,R7 ;保存数据个数
  2823. MOV R2,A
  2824. PUSH DPH
  2825. PUSH DPL
  2826. CLR A ;初始化累加和
  2827. MOV R4,A
  2828. MOV R5,A
  2829. DM11: MOVX A,@DPTR ;读取一个数据
  2830. ADD A,R5 ;累加到累加和中
  2831. MOV R5,A
  2832. JNC DM12
  2833. INC R4
  2834. DM12: INC DPTR ;调整指针
  2835. DJNZ R2,DM11 ;累加完全部数据
  2836. LCALL D457 ;求平均值(R4R5/R7-→R3)
  2837. MOV A,R3 ;取平均值
  2838. POP DPL
  2839. POP DPH
  2840. RET
  2841. ;(31) 标号: DDM2 功能:求双字节十六进制无符号数据块的平均值
  2842. ;入口条件:数据块的首址在DPTR中,双字节数据总个数在R7中。
  2843. ;出口信息:平均值在R4、R5中。
  2844. ;影响资源:PSW、A、R2~R6 堆栈需求: 4字节
  2845. DDM2: MOV A,R7 ;保存数据个数
  2846. MOV R2,A ;初始化数据指针
  2847. PUSH DPL ;保持首址
  2848. PUSH DPH
  2849. CLR A ;初始化累加和
  2850. MOV R3,A
  2851. MOV R4,A
  2852. MOV R5,A
  2853. DM20: MOVX A,@DPTR ;读取一个数据的高字节
  2854. MOV B,A
  2855. INC DPTR
  2856. MOVX A,@DPTR ;读取一个数据的低字节
  2857. INC DPTR
  2858. ADD A,R5 ;累加到累加和中
  2859. MOV R5,A
  2860. MOV A,B
  2861. ADDC A,R4
  2862. MOV R4,A
  2863. JNC DM21
  2864. INC R3
  2865. DM21: DJNZ R2,DM20 ;累加完全部数据
  2866. POP DPH ;恢复首址
  2867. POP DPL
  2868. LJMP DV31 ;求R3R4R5/R7-→R4R5,得到平均值
  2869. ;(32) 标号: XR1 功能:求单字节数据块的(异或)校验和
  2870. ;入口条件:数据块的首址在DPTR中,数据的个数在R6、R7中。
  2871. ;出口信息:校验和在累加器A中。
  2872. ;影响资源:PSW、A、B、R4~R7 堆栈需求: 2字节
  2873. XR1: MOV R4,DPH ;保存数据块的首址
  2874. MOV R5,DPL
  2875. MOV A,R7 ;双字节计数器调整
  2876. JZ XR10
  2877. INC R6
  2878. XR10: MOV B,#0 ;校验和初始化
  2879. XR11: MOVX A,@DPTR ;读取一个数据
  2880. XRL B,A ;异或运算
  2881. INC DPTR ;指向下一个数据
  2882. DJNZ R7,XR11 ;双字节计数器减一
  2883. DJNZ R6,XR11
  2884. MOV DPH,R4 ;恢复数据首址
  2885. MOV DPL,R5
  2886. MOV A,B ;取校验和
  2887. RET
  2888. ;(33) 标号: XR2 功能:求双字节数据块的(异或)校验和
  2889. ;入口条件:数据块的首址在DPTR中,双字节数据总个数在R6、R7中。
  2890. ;出口信息:校验和在R2、R3中。
  2891. ;影响资源:PSW、A、R2~R7 堆栈需求: 2字节
  2892. XR2: MOV R4,DPH ;保存数据块的首址
  2893. MOV R5,DPL
  2894. MOV A,R7 ;双字节计数器调整
  2895. JZ XR20
  2896. INC R6
  2897. XR20: CLR A ;校验和初始化
  2898. MOV R2,A
  2899. MOV R3,A
  2900. XR21: MOVX A,@DPTR ;读取一个数据的高字节
  2901. XRL A,R2 ;异或运算
  2902. MOV R2,A
  2903. INC DPTR
  2904. MOVX A,@DPTR ;读取一个数据的低字节
  2905. XRL A,R3 ;异或运算
  2906. MOV R3,A
  2907. INC DPTR ;指向下一个数据
  2908. DJNZ R7,XR21 ;双字节计数器减一
  2909. DJNZ R6,XR21
  2910. MOV DPH,R4 ;恢复数据首址
  2911. MOV DPL,R5
  2912. RET
  2913. ;(34) 标号: SORT 功能:单字节无符号数据块排序(增序)
  2914. ;入口条件:数据块的首址在R0中,字节数在R7中。
  2915. ;出口信息:完成排序(增序)
  2916. ;影响资源:PSW、A、R2~R6 堆栈需求: 2字节
  2917. SORT: MOV A,R7
  2918. MOV R5,A ;比较次数初始化
  2919. SRT1: CLR F0 ;交换标志初始化
  2920. MOV A,R5 ;取上遍比较次数
  2921. DEC A ;本遍比上遍减少一次
  2922. MOV R5,A ;保存本遍次数
  2923. MOV R2,A ;复制到计数器中
  2924. JZ SRT5 ;若为零,排序结束
  2925. MOV A,R0 ;保存数据指针
  2926. MOV R6,A
  2927. SRT2: MOV A,@R0 ;读取一个数据
  2928. MOV R3,A
  2929. INC R0 ;指向下一个数据
  2930. MOV A,@R0 ;再读取一个数据
  2931. MOV R4,A
  2932. CLR C
  2933. SUBB A,R3 ;比较两个数据的大小
  2934. JNC SRT4 ;顺序正确(增序或相同),不必交换
  2935. SETB F0 ;设立交换标志
  2936. MOV A,R3 ;将两个数据交换位置
  2937. MOV @R0,A
  2938. DEC R0
  2939. MOV A,R4
  2940. MOV @R0,A
  2941. INC R0 ;指向下一个数据
  2942. SRT4: DJNZ R2,SRT2 ;完成本遍的比较次数
  2943. MOV A,R6 ;恢复数据首址
  2944. MOV R0,A
  2945. JB F0,SRT1 ;本遍若进行过交换,则需继续排序
  2946. SRT5: RET ;排序结束
  2947. END
  2948. ;(二) MCS-51 浮点运算子程序库及其使用说明
  2949. ;本浮点子程序库有三个不同层次的版本,以便适应不同的应用场合:
  2950. ;1.小型库(FQ51A.ASM):只包含浮点加、减、乘、除子程序。
  2951. ;2.中型库(FQ51B.ASM):在小型库的基础上再增加绝对值、倒数、比较、平方、开平方、
  2952. ;数制转换等子程序。
  2953. ;3.大型库(FQ51.ASM):包含本说明书中的全部子程序。
  2954. ;为便于读者使用本程序库,先将有关约定说明如下:
  2955. ;1.双字节定点操作数:用[R0]或[R1]来表示存放在由R0或R1指示的连续单元中的数
  2956. ;据,地址小的单元存放高字节。如果[R0]=1234H,若(R0)=30H,则(30H)=12H,(31H)=34H。
  2957. ;2.二进制浮点操作数:用三个字节表示,第一个字节的最高位为数符,其余七位为
  2958. ;阶码(补码形式),第二字节为尾数的高字节,第三字节为尾数的低字节,尾数用双字节
  2959. ;纯小数(原码)来表示。当尾数的最高位为1时,便称为规格化浮点数,简称操作数。在
  2960. ;程序说明中,也用[R0]或[R1]来表示R0或R1指示的浮点操作数,例如:当[R0]=-6.000时,
  2961. ;则二进制浮点数表示为83C000H。若(R0)=30H,则(30H)=83H,(31H)=0C0H,(32H)=00H。
  2962. ;3.十进制浮点操作数:用三个字节表示,第一个字节的最高位为数符,其余七位为
  2963. ;阶码(二进制补码形式),第二字节为尾数的高字节,第三字节为尾数的低字节,尾数用
  2964. ;双字节BCD码纯小数(原码)来表示。当十进制数的绝对值大于1时,阶码就等于整数
  2965. ;部分的位数,如 876.5 的阶码是03H,-876.5 的阶码是 83H;当十进制数的绝对值小于1
  2966. ;时,阶码就等于 80H 减去小数点后面零的个数,例如 0.00382 的阶码是 7EH,-0.00382
  2967. ;的阶码是 0FEH。在程序说明中,用[R0]或[R1]来表示R0或R1指示的十进制浮点操作数。例
  2968. ;如有一个十进制浮点操作数存放在30H、31H、32H中,数值是 -0.07315,即-0.7315乘以10
  2969. ;的-1次方,则(30H)=0FFH,31H=73H,(32H)=15H。若用[R0]来指向它,则应使(R0)=30H。
  2970. ;4.运算精度:单次定点运算精度为结果最低位的当量值;单次二进制浮点算术运算
  2971. ;的精度优于十万分之三;单次二进制浮点超越函数运算的精度优于万分之一;BCD码浮
  2972. ;点数本身的精度比较低(万分之一到千分之一),不宜作为运算的操作数,仅用于输入或
  2973. ;输出时的数制转换。不管那种数据格式,随着连续运算的次数增加,精度都会下降。
  2974. ;5.工作区:数据工作区固定在A、B、R2~R7,数符或标志工作区固定在PSW和23H单
  2975. ;元(位1CH~1FH)。在浮点系统中,R2、R3、R4和位1FH为第一工作区,R5、R6、R7和位1EH
  2976. ;为第二工作区。用户只要不在工作区中存放无关的或非消耗性的信息,程序就具有较好的
  2977. ;透明性。
  2978. ;6.子程序调用范例:由于本程序库特别注意了各子程序接口的相容性,很容易采用
  2979. ;积木方式(或流水线方式)完成一个公式的计算。以浮点运算为例:
  2980. ;计算 y = Ln √ | Sin (ab/c+d) |
  2981. ;已知:a=-123.4;b=0.7577;c=56.34;d=1.276; 它们分别存放在30H、33H、36H、
  2982. ;39H开始的连续三个单元中。用BCD码浮点数表示时,分别为a=831234H;b=007577H;
  2983. ;c=025634H;d=011276H。
  2984. ;求解过程:通过调用BTOF子程序,将各变量转换成二进制浮点操作数,再进行各
  2985. ;种运算,最后调用FTOB子程序,还原成十进制形式,供输出使用。程序如下:
  2986. TEST: MOV R0,#39H ;指向BCD码浮点操作数d
  2987. LCALL BTOF ;将其转换成二进制浮点操作数
  2988. MOV R0,#36H ;指向BCD码浮点操作数c
  2989. LCALL BTOF ;将其转换成二进制浮点操作数
  2990. MOV R0,#33H ;指向BCD码浮点操作数b
  2991. LCALL BTOF ;将其转换成二进制浮点操作数
  2992. MOV R0,#30H ;指向BCD码浮点操作数a
  2993. LCALL BTOF ;将其转换成二进制浮点操作数
  2994. MOV R1,#33H ;指向二进制浮点操作数b
  2995. LCALL FMUL ;进行浮点乘法运算
  2996. MOV R1,#36H ;指向二进制浮点操作数c
  2997. LCALL FDIV ;进行浮点除法运算
  2998. MOV R1,#39H ;指向二进制浮点操作数d
  2999. LCALL FADD ;进行浮点加法运算
  3000. LCALL FSIN ;进行浮点正弦运算
  3001. LCALL FABS ;进行浮点绝对值运算
  3002. LCALL FSQR ;进行浮点开平方运算
  3003. LCALL FLN ;进行浮点对数运算
  3004. LCALL FTOB ;将结果转换成BCD码浮点数
  3005. STOP: LJMP STOP
  3006. END
  3007. ;运行结果,[R0]=804915H,即y=-0.4915,比较精确的结果应该是-0.491437。
  3008. ;(1) 标号: FSDT 功能:浮点数格式化
  3009. ;入口条件:待格式化浮点操作数在[R0]中。
  3010. ;出口信息:已格式化浮点操作数仍在[R0]中。
  3011. ;影响资源:PSW、A、R2、R3、R4、位1FH 堆栈需求: 6字节
  3012. FSDT: LCALL MVR0 ;将待格式化操作数传送到第一工作区中
  3013. LCALL RLN ;通过左规完成格式化
  3014. LJMP MOV0 ;将已格式化浮点操作数传回到[R0]中
  3015. ;(2) 标号: FADD 功能:浮点数加法
  3016. ;入口条件:被加数在[R0]中,加数在[R1]中。
  3017. ;出口信息:OV=0时,和仍在[R0]中,OV=1时,溢出。
  3018. ;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 6字节
  3019. FADD: CLR F0 ;设立加法标志
  3020. SJMP AS ;计算代数和
  3021. ;(3) 标号: FSUB 功能:浮点数减法
  3022. ;入口条件:被减数在[R0]中,减数在[R1]中。
  3023. ;出口信息:OV=0时,差仍在[R0]中,OV=1时,溢出。
  3024. ;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节
  3025. FSUB: SETB F0 ;设立减法标志
  3026. AS: LCALL MVR1 ;计算代数和。先将[R1]传送到第二工作区
  3027. MOV C,F0 ;用加减标志来校正第二操作数的有效符号
  3028. RRC A
  3029. XRL A,@R1
  3030. MOV C,ACC.7
  3031. ASN: MOV 1EH,C ;将第二操作数的有效符号存入位1EH中
  3032. XRL A,@R0 ;与第一操作数的符号比较
  3033. RLC A
  3034. MOV F0,C ;保存比较结果
  3035. LCALL MVR0 ;将[R0]传送到第一工作区中
  3036. LCALL AS1 ;在工作寄存器中完成代数运算
  3037. MOV0: INC R0 ;将结果传回到[R0]中的子程序入口
  3038. INC R0
  3039. MOV A,R4 ;传回尾数的低字节
  3040. MOV @R0,A
  3041. DEC R0
  3042. MOV A,R3 ;传回尾数的高字节
  3043. MOV @R0,A
  3044. DEC R0
  3045. MOV A,R2 ;取结果的阶码
  3046. MOV C,1FH ;取结果的数符
  3047. MOV ACC.7,C ;拼入阶码中
  3048. MOV @R0,A
  3049. CLR ACC.7 ;不考虑数符
  3050. CLR OV ;清除溢出标志
  3051. CJNE A,#3FH,MV01;阶码是否上溢?
  3052. SETB OV ;设立溢出标志
  3053. MV01: MOV A,@R0 ;取出带数符的阶码
  3054. RET
  3055. MVR0: MOV A,@R0 ;将[R0]传送到第一工作区中的子程序
  3056. MOV C,ACC.7 ;将数符保存在位1FH中
  3057. MOV 1FH,C
  3058. MOV C,ACC.6 ;将阶码扩充为8bit补码
  3059. MOV ACC.7,C
  3060. MOV R2,A ;存放在R2中
  3061. INC R0
  3062. MOV A,@R0 ;将尾数高字节存放在R3中
  3063. MOV R3,A
  3064. INC R0
  3065. MOV A,@R0 ;将尾数低字节存放在R4中
  3066. MOV R4,A
  3067. DEC R0 ;恢复数据指针
  3068. DEC R0
  3069. RET
  3070. MVR1: MOV A,@R1 ;将[R1]传送到第二工作区中的子程序
  3071. MOV C,ACC.7 ;将数符保存在位1EH中
  3072. MOV 1EH,C
  3073. MOV C,ACC.6 ;将阶码扩充为8bit补码
  3074. MOV ACC.7,C
  3075. MOV R5,A ;存放在R5中
  3076. INC R1
  3077. MOV A,@R1 ;将尾数高字节存放在R6中
  3078. MOV R6,A
  3079. INC R1
  3080. MOV A,@R1 ;将尾数低字节存放在R7中
  3081. MOV R7,A
  3082. DEC R1 ;恢复数据指针
  3083. DEC R1
  3084. RET
  3085. AS1: MOV A,R6 ;读取第二操作数尾数高字节
  3086. ORL A,R7
  3087. JZ AS2 ;第二操作数为零,不必运算
  3088. MOV A,R3 ;读取第一操作数尾数高字节
  3089. ORL A,R4
  3090. JNZ EQ1
  3091. MOV A,R6 ;第一操作数为零,结果以第二操作数为准
  3092. MOV R3,A
  3093. MOV A,R7
  3094. MOV R4,A
  3095. MOV A,R5
  3096. MOV R2,A
  3097. MOV C,1EH
  3098. MOV 1FH,C
  3099. AS2: RET
  3100. EQ1: MOV A,R2 ;对阶,比较两个操作数的阶码
  3101. XRL A,R5
  3102. JZ AS4 ;阶码相同,对阶结束
  3103. JB ACC.7,EQ3;阶符互异
  3104. MOV A,R2 ;阶符相同,比较大小
  3105. CLR C
  3106. SUBB A,R5
  3107. JC EQ4
  3108. EQ2: CLR C ;第二操作数右规一次
  3109. MOV A,R6 ;尾数缩小一半
  3110. RRC A
  3111. MOV R6,A
  3112. MOV A,R7
  3113. RRC A
  3114. MOV R7,A
  3115. INC R5 ;阶码加一
  3116. ORL A,R6 ;尾数为零否?
  3117. JNZ EQ1 ;尾数不为零,继续对阶
  3118. MOV A,R2 ;尾数为零,提前结束对阶
  3119. MOV R5,A
  3120. SJMP AS4
  3121. EQ3: MOV A,R2 ;判断第一操作数阶符
  3122. JNB ACC.7,EQ2;如为正,右规第二操作数
  3123. EQ4: CLR C
  3124. LCALL RR1 ;第一操作数右规一次
  3125. ORL A,R3 ;尾数为零否?
  3126. JNZ EQ1 ;不为零,继续对阶
  3127. MOV A,R5 ;尾数为零,提前结束对阶
  3128. MOV R2,A
  3129. AS4: JB F0,AS5 ;尾数加减判断
  3130. MOV A,R4 ;尾数相加
  3131. ADD A,R7
  3132. MOV R4,A
  3133. MOV A,R3
  3134. ADDC A,R6
  3135. MOV R3,A
  3136. JNC AS2
  3137. LJMP RR1 ;有进位,右规一次
  3138. AS5: CLR C ;比较绝对值大小
  3139. MOV A,R4
  3140. SUBB A,R7
  3141. MOV B,A
  3142. MOV A,R3
  3143. SUBB A,R6
  3144. JC AS6
  3145. MOV R4,B ;第一尾数减第二尾数
  3146. MOV R3,A
  3147. LJMP RLN ;结果规格化
  3148. AS6: CPL 1FH ;结果的符号与第一操作数相反
  3149. CLR C ;结果的绝对值为第二尾数减第一尾数
  3150. MOV A,R7
  3151. SUBB A,R4
  3152. MOV R4,A
  3153. MOV A,R6
  3154. SUBB A,R3
  3155. MOV R3,A
  3156. RLN: MOV A,R3 ;浮点数规格化
  3157. ORL A,R4 ;尾数为零否?
  3158. JNZ RLN1
  3159. MOV R2,#0C1H;阶码取最小值
  3160. RET
  3161. RLN1: MOV A,R3
  3162. JB ACC.7,RLN2;尾数最高位为一否?
  3163. CLR C ;不为一,左规一次
  3164. LCALL RL1
  3165. SJMP RLN ;继续判断
  3166. RLN2: CLR OV ;规格化结束
  3167. RET
  3168. RL1: MOV A,R4 ;第一操作数左规一次
  3169. RLC A ;尾数扩大一倍
  3170. MOV R4,A
  3171. MOV A,R3
  3172. RLC A
  3173. MOV R3,A
  3174. DEC R2 ;阶码减一
  3175. CJNE R2,#0C0H,RL1E;阶码下溢否?
  3176. CLR A
  3177. MOV R3,A ;阶码下溢,操作数以零计
  3178. MOV R4,A
  3179. MOV R2,#0C1H
  3180. RL1E: CLR OV
  3181. RET
  3182. RR1: MOV A,R3 ;第一操作数右规一次
  3183. RRC A ;尾数缩小一半
  3184. MOV R3,A
  3185. MOV A,R4
  3186. RRC A
  3187. MOV R4,A
  3188. INC R2 ;阶码加一
  3189. CLR OV ;清溢出标志
  3190. CJNE R2,#40H,RR1E;阶码上溢否?
  3191. MOV R2,#3FH ;阶码溢出
  3192. SETB OV
  3193. RR1E: RET
  3194. ;(4) 标号: FMUL 功能:浮点数乘法
  3195. ;入口条件:被乘数在[R0]中,乘数在[R1]中。
  3196. ;出口信息:OV=0时,积仍在[R0]中,OV=1时,溢出。
  3197. ;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节
  3198. FMUL: LCALL MVR0 ;将[R0]传送到第一工作区中
  3199. MOV A,@R0
  3200. XRL A,@R1 ;比较两个操作数的符号
  3201. RLC A
  3202. MOV 1FH,C ;保存积的符号
  3203. LCALL MUL0 ;计算积的绝对值
  3204. LJMP MOV0 ;将结果传回到[R0]中
  3205. MUL0: LCALL MVR1 ;将[R1]传送到第二工作区中
  3206. MUL1: MOV A,R3 ;第一尾数为零否?
  3207. ORL A,R4
  3208. JZ MUL6
  3209. MOV A,R6 ;第二尾数为零否?
  3210. ORL A,R7
  3211. JZ MUL5
  3212. MOV A,R7 ;计算R3R4×R6R7-→R3R4
  3213. MOV B,R4
  3214. MUL AB
  3215. MOV A,B
  3216. XCH A,R7
  3217. MOV B,R3
  3218. MUL AB
  3219. ADD A,R7
  3220. MOV R7,A
  3221. CLR A
  3222. ADDC A,B
  3223. XCH A,R4
  3224. MOV B,R6
  3225. MUL AB
  3226. ADD A,R7
  3227. MOV R7,A
  3228. MOV A,B
  3229. ADDC A,R4
  3230. MOV R4,A
  3231. CLR A
  3232. RLC A
  3233. XCH A,R3
  3234. MOV B,R6
  3235. MUL AB
  3236. ADD A,R4
  3237. MOV R4,A
  3238. MOV A,B
  3239. ADDC A,R3
  3240. MOV R3,A
  3241. JB ACC.7,MUL2;积为规格化数否?
  3242. MOV A,R7 ;左规一次
  3243. RLC A
  3244. MOV R7,A
  3245. LCALL RL1
  3246. MUL2: MOV A,R7
  3247. JNB ACC.7,MUL3
  3248. INC R4
  3249. MOV A,R4
  3250. JNZ MUL3
  3251. INC R3
  3252. MOV A,R3
  3253. JNZ MUL3
  3254. MOV R3,#80H
  3255. INC R2
  3256. MUL3: MOV A,R2 ;求积的阶码
  3257. ADD A,R5
  3258. MD: MOV R2,A ;阶码溢出判断
  3259. JB ACC.7,MUL4
  3260. JNB ACC.6,MUL6
  3261. MOV R2,#3FH ;阶码上溢,设立标志
  3262. SETB OV
  3263. RET
  3264. MUL4: JB ACC.6,MUL6
  3265. MUL5: CLR A ;结果清零(因子为零或阶码下溢)
  3266. MOV R3,A
  3267. MOV R4,A
  3268. MOV R2,#41H
  3269. MUL6: CLR OV
  3270. RET
  3271. ;(5) 标号: FDIV 功能:浮点数除法
  3272. ;入口条件:被除数在[R0]中,除数在[R1]中。
  3273. ;出口信息:OV=0时,商仍在[R0]中,OV=1时,溢出。
  3274. ;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 5字节
  3275. FDIV: INC R0
  3276. MOV A,@R0
  3277. INC R0
  3278. ORL A,@R0
  3279. DEC R0
  3280. DEC R0
  3281. JNZ DIV1
  3282. MOV @R0,#41H;被除数为零,不必运算
  3283. CLR OV
  3284. RET
  3285. DIV1: INC R1
  3286. MOV A,@R1
  3287. INC R1
  3288. ORL A,@R1
  3289. DEC R1
  3290. DEC R1
  3291. JNZ DIV2
  3292. SETB OV ;除数为零,溢出
  3293. RET
  3294. DIV2: LCALL MVR0 ;将[R0]传送到第一工作区中
  3295. MOV A,@R0
  3296. XRL A,@R1 ;比较两个操作数的符号
  3297. RLC A
  3298. MOV 1FH,C ;保存结果的符号
  3299. LCALL MVR1 ;将[R1]传送到第二工作区中
  3300. LCALL DIV3 ;调用工作区浮点除法
  3301. LJMP MOV0 ;回传结果
  3302. DIV3: CLR C ;比较尾数的大小
  3303. MOV A,R4
  3304. SUBB A,R7
  3305. MOV A,R3
  3306. SUBB A,R6
  3307. JC DIV4
  3308. LCALL RR1 ;被除数右规一次
  3309. SJMP DIV3
  3310. DIV4: CLR A ;借用R0R1R2作工作寄存器
  3311. XCH A,R0 ;清零并保护之
  3312. PUSH ACC
  3313. CLR A
  3314. XCH A,R1
  3315. PUSH ACC
  3316. MOV A,R2
  3317. PUSH ACC
  3318. MOV B,#10H ;除法运算,R3R4/R6R7-→R0R1
  3319. DIV5: CLR C
  3320. MOV A,R1
  3321. RLC A
  3322. MOV R1,A
  3323. MOV A,R0
  3324. RLC A
  3325. MOV R0,A
  3326. MOV A,R4
  3327. RLC A
  3328. MOV R4,A
  3329. XCH A,R3
  3330. RLC A
  3331. XCH A,R3
  3332. MOV F0,C
  3333. CLR C
  3334. SUBB A,R7
  3335. MOV R2,A
  3336. MOV A,R3
  3337. SUBB A,R6
  3338. ANL C,/F0
  3339. JC DIV6
  3340. MOV R3,A
  3341. MOV A,R2
  3342. MOV R4,A
  3343. INC R1
  3344. DIV6: DJNZ B,DIV5
  3345. MOV A,R6 ;四舍五入
  3346. CLR C
  3347. RRC A
  3348. SUBB A,R3
  3349. CLR A
  3350. ADDC A,R1 ;将结果存回R3R4
  3351. MOV R4,A
  3352. CLR A
  3353. ADDC A,R0
  3354. MOV R3,A
  3355. POP ACC ;恢复R0R1R2
  3356. MOV R2,A
  3357. POP ACC
  3358. MOV R1,A
  3359. POP ACC
  3360. MOV R0,A
  3361. MOV A,R2 ;计算商的阶码
  3362. CLR C
  3363. SUBB A,R5
  3364. LCALL MD ;阶码检验
  3365. LJMP RLN ;规格化
  3366. ;(6) 标号: FCLR 功能:浮点数清零
  3367. ;入口条件:操作数在[R0]中。
  3368. ;出口信息:操作数被清零。
  3369. ;影响资源:A 堆栈需求: 2字节
  3370. FCLR: INC R0
  3371. INC R0
  3372. CLR A
  3373. MOV @R0,A
  3374. DEC R0
  3375. MOV @R0,A
  3376. DEC R0
  3377. MOV @R0,#41H
  3378. RET
  3379. ;(7) 标号: FZER 功能:浮点数判零
  3380. ;入口条件:操作数在[R0]中。
  3381. ;出口信息:若累加器A为零,则操作数[R0]为零,否则不为零。
  3382. ;影响资源:A 堆栈需求: 2字节
  3383. FZER: INC R0
  3384. INC R0
  3385. MOV A,@R0
  3386. DEC R0
  3387. ORL A,@R0
  3388. DEC R0
  3389. JNZ ZERO
  3390. MOV @R0,#41H
  3391. ZERO: RET
  3392. ;(8) 标号: FMOV 功能:浮点数传送
  3393. ;入口条件:源操作数在[R1]中,目标地址为[R0]。
  3394. ;出口信息:[R0]=[R1],[R1]不变。
  3395. ;影响资源:A 堆栈需求: 2字节
  3396. FMOV: INC R0
  3397. INC R0
  3398. INC R1
  3399. INC R1
  3400. MOV A,@R1
  3401. MOV @R0,A
  3402. DEC R0
  3403. DEC R1
  3404. MOV A,@R1
  3405. MOV @R0,A
  3406. DEC R0
  3407. DEC R1
  3408. MOV A,@R1
  3409. MOV @R0,A
  3410. RET
  3411. ;(9) 标号: FPUS 功能:浮点数压栈
  3412. ;入口条件:操作数在[R0]中。
  3413. ;出口信息:操作数压入栈顶。
  3414. ;影响资源:A、R2、R3 堆栈需求: 5字节
  3415. FPUS: POP ACC ;将返回地址保存在R2R3中
  3416. MOV R2,A
  3417. POP ACC
  3418. MOV R3,A
  3419. MOV A,@R0 ;将操作数压入堆栈
  3420. PUSH ACC
  3421. INC R0
  3422. MOV A,@R0
  3423. PUSH ACC
  3424. INC R0
  3425. MOV A,@R0
  3426. PUSH ACC
  3427. DEC R0
  3428. DEC R0
  3429. MOV A,R3 ;将返回地址压入堆栈
  3430. PUSH ACC
  3431. MOV A,R2
  3432. PUSH ACC
  3433. RET ;返回主程序
  3434. ;(10) 标号: FPOP 功能:浮点数出栈
  3435. ;入口条件:操作数处于栈顶。
  3436. ;出口信息:操作数弹至[R0]中。
  3437. ;影响资源:A、R2、R3 堆栈需求: 2字节
  3438. FPOP: POP ACC ;将返回地址保存在R2R3中
  3439. MOV R2,A
  3440. POP ACC
  3441. MOV R3,A
  3442. INC R0
  3443. INC R0
  3444. POP ACC ;将操作数弹出堆栈,传送到[R0]中
  3445. MOV @R0,A
  3446. DEC R0
  3447. POP ACC
  3448. MOV @R0,A
  3449. DEC R0
  3450. POP ACC
  3451. MOV @R0,A
  3452. MOV A,R3 ;将返回地址压入堆栈
  3453. PUSH ACC
  3454. MOV A,R2
  3455. PUSH ACC
  3456. RET ;返回主程序
  3457. ;(11) 标号: FCMP 功能:浮点数代数值比较(不影响待比较操作数)
  3458. ;入口条件:待比较操作数分别在[R0]和[R1]中。
  3459. ;出口信息:若CY=1,则[R0] < [R1],若CY=0且A=0则 [R0] = [R1],否则[R0] > [R1]。
  3460. ;影响资源:A、B、PSW 堆栈需求: 2字节
  3461. FCMP: MOV A,@R0 ;数符比较
  3462. XRL A,@R1
  3463. JNB ACC.7,CMP2
  3464. MOV A,@R0 ;两数异号,以[R0]数符为准
  3465. RLC A
  3466. MOV A,#0FFH
  3467. RET
  3468. CMP2: MOV A,@R1 ;两数同号,准备比较阶码
  3469. MOV C,ACC.6
  3470. MOV ACC.7,C
  3471. MOV B,A
  3472. MOV A,@R0
  3473. MOV C,ACC.7
  3474. MOV F0,C ;保存[R0]的数符
  3475. MOV C,ACC.6
  3476. MOV ACC.7,C
  3477. CLR C ;比较阶码
  3478. SUBB A,B
  3479. JZ CMP6
  3480. RLC A ;取阶码之差的符号
  3481. JNB F0,CMP5
  3482. CPL C ;[R0]为负时,结果取反
  3483. CMP5: MOV A,#0FFH ;两数不相等
  3484. RET
  3485. CMP6: INC R0 ;阶码相同时,准备比较尾数
  3486. INC R0
  3487. INC R1
  3488. INC R1
  3489. CLR C
  3490. MOV A,@R0
  3491. SUBB A,@R1
  3492. MOV B,A ;保存部分差
  3493. DEC R0
  3494. DEC R1
  3495. MOV A,@R0
  3496. SUBB A,@R1
  3497. DEC R0
  3498. DEC R1
  3499. ORL A,B ;生成是否相等信息
  3500. JZ CMP7
  3501. JNB F0,CMP7
  3502. CPL C ;[R0]为负时,结果取反
  3503. CMP7: RET
  3504. ;(12) 标号: FABS 功能:浮点绝对值函数
  3505. ;入口条件:操作数在[R0]中。
  3506. ;出口信息:结果仍在[R0]中。
  3507. ;影响资源:A 堆栈需求: 2字节
  3508. FABS:         MOV A,@R0         ;读取操作数的阶码
  3509.         CLR ACC.7         ;清除数符
  3510.         MOV @R0,A         ;回传阶码
  3511.         RET
  3512. ;(13) 标号: FSGN 功能:浮点符号函数
  3513. ;入口条件:操作数在[R0]中。
  3514. ;出口信息:累加器 A=1 时为正数,A=0FFH时为负数,A=0 时为零。
  3515. ;影响资源:PSW、A 堆栈需求: 2字节
  3516. FSGN: INC R0 ;读尾数
  3517. MOV A,@R0
  3518. INC R0
  3519. ORL A,@R0
  3520. DEC R0
  3521. DEC R0
  3522. JNZ SGN
  3523. RET ;尾数为零,结束
  3524. SGN: MOV A,@R0 ;读取操作数的阶码
  3525. RLC A ;取数符
  3526. MOV A,#1 ;按正数初始化
  3527. JNC SGN1 ;是正数,结束
  3528. MOV A,#0FFH ;是负数,改变标志
  3529. SGN1: RET
  3530. ;(14) 标号: FINT 功能:浮点取整函数
  3531. ;入口条件:操作数在[R0]中。
  3532. ;出口信息:结果仍在[R0]中。
  3533. ;影响资源:PSW、A、R2、R3、R4、位1FH 堆栈需求: 6字节
  3534. FINT: LCALL MVR0 ;将[R0]传送到第一工作区中
  3535. LCALL INT ;在工作寄存器中完成取整运算
  3536. LJMP MOV0 ;将结果传回到[R0]中
  3537. INT: MOV A,R3
  3538. ORL A,R4
  3539. JNZ INTA
  3540. CLR 1FH ;尾数为零,阶码也清零,结束取整
  3541. MOV R2,#41H
  3542. RET
  3543. INTA: MOV A,R2
  3544. JZ INTB ;阶码为零否?
  3545. JB ACC.7,INTB;阶符为负否?
  3546. CLR C
  3547. SUBB A,#10H ;阶码小于16否?
  3548. JC INTD
  3549. RET ;阶码大于16,已经是整数
  3550. INTB: CLR A ;绝对值小于一,取整后正数为零,负数为负一
  3551. MOV R4,A
  3552. MOV C,1FH
  3553. RRC A
  3554. MOV R3,A
  3555. RL A
  3556. MOV R2,A
  3557. JNZ INTC
  3558. MOV R2,#41H
  3559. INTC: RET
  3560. INTD: CLR F0 ;舍尾标志初始化
  3561. INTE: CLR C
  3562. LCALL RR1 ;右规一次
  3563. ORL C,F0 ;记忆舍尾情况
  3564. MOV F0,C
  3565. CJNE R2,#10H,INTE;阶码达到16(尾数完全为整数)否?
  3566. JNB F0,INTF ;舍去部分为零否?
  3567. JNB 1FH,INTF;操作数为正数否?
  3568. INC R4 ;对于带小数的负数,向下取整
  3569. MOV A,R4
  3570. JNZ INTF
  3571. INC R3
  3572. INTF: LJMP RLN ;将结果规格化
  3573. ;(15) 标号: FRCP 功能:浮点倒数函数
  3574. ;入口条件:操作数在[R0]中。
  3575. ;出口信息:OV=0时,结果仍在[R0]中,OV=1时,溢出。
  3576. ;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 5字节
  3577. FRCP: MOV A,@R0
  3578. MOV C,ACC.7
  3579. MOV 1FH,C ;保存数符
  3580. MOV C,ACC.6 ;绝对值传送到第二工作区
  3581. MOV ACC.7,C
  3582. MOV R5,A
  3583. INC R0
  3584. MOV A,@R0
  3585. MOV R6,A
  3586. INC R0
  3587. MOV A,@R0
  3588. MOV R7,A
  3589. DEC R0
  3590. DEC R0
  3591. ORL A,R6
  3592. JNZ RCP
  3593. SETB OV ;零不能求倒数,设立溢出标志
  3594. RET
  3595. RCP: MOV A,R6
  3596. JB ACC.7,RCP2;操作数格式化否?
  3597. CLR C ;格式化之
  3598. MOV A,R7
  3599. RLC A
  3600. MOV R7,A
  3601. MOV A,R6
  3602. RLC A
  3603. MOV R6,A
  3604. DEC R5
  3605. SJMP RCP
  3606. RCP2: MOV R2,#1 ;将数值1.00传送到第一工作区
  3607. MOV R3,#80H
  3608. MOV R4,#0
  3609. LCALL DIV3 ;调用工作区浮点除法,求得倒数
  3610. LJMP MOV0 ;回传结果
  3611. ;(16) 标号: FSQU 功能:浮点数平方
  3612. ;入口条件:操作数在[R0]中。
  3613. ;出口信息:OV=0时,平方值仍然在[R0]中,OV=1时溢出。
  3614. ;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 9字节
  3615. FSQU: MOV A,R0 ;将操作数
  3616. XCH A,R1 ;同时作为乘数
  3617. PUSH ACC ;保存R1指针
  3618. LCALL FMUL ;进行乘法运算
  3619. POP ACC
  3620. MOV R1,A ;恢复R1指针
  3621. RET
  3622. ;(17) 标号: FSQR 功能:浮点数开平方(快速逼近算法)
  3623. ;入口条件:操作数在[R0]中。
  3624. ;出口信息:OV=0时,平方根仍在[R0]中,OV=1时,负数开平方出错。
  3625. ;影响资源:PSW、A、B、R2~R7 堆栈需求: 2字节
  3626. FSQR: MOV A,@R0
  3627. JNB ACC.7,SQR
  3628. SETB OV ;负数开平方,出错
  3629. RET
  3630. SQR: INC R0
  3631. INC R0
  3632. MOV A,@R0
  3633. DEC R0
  3634. ORL A,@R0
  3635. DEC R0
  3636. JNZ SQ
  3637. MOV @R0,#41H;尾数为零,不必运算
  3638. CLR OV
  3639. RET
  3640. SQ: MOV A,@R0
  3641. MOV C,ACC.6 ;将阶码扩展成8bit补码
  3642. MOV ACC.7,C
  3643. INC A ;加一
  3644. CLR C
  3645. RRC A ;除二
  3646. MOV @R0,A ;得到平方根的阶码,回存之
  3647. INC R0 ;指向被开方数尾数的高字节
  3648. JC SQR0 ;原被开方数的阶码是奇数吗?
  3649. MOV A,@R0 ;是奇数,尾数右规一次
  3650. RRC A
  3651. MOV @R0,A
  3652. INC R0
  3653. MOV A,@R0
  3654. RRC A
  3655. MOV @R0,A
  3656. DEC R0
  3657. SQR0: MOV A,@R0
  3658. JZ SQR9 ;尾数为零,不必运算
  3659. MOV R2,A ;将尾数传送到R2R3中
  3660. INC R0
  3661. MOV A,@R0
  3662. MOV R3,A
  3663. MOV A,R2 ;快速开方,参阅定点子程序说明
  3664. ADD A,#57H
  3665. JC SQR2
  3666. ADD A,#45H
  3667. JC SQR1
  3668. ADD A,#24H
  3669. MOV B,#0E3H
  3670. MOV R4,#80H
  3671. SJMP SQR3
  3672. SQR1: MOV B,#0B2H
  3673. MOV R4,#0A0H
  3674. SJMP SQR3
  3675. SQR2: MOV B,#8DH
  3676. MOV R4,#0D0H
  3677. SQR3: MUL AB
  3678. MOV A,B
  3679. ADD A,R4
  3680. MOV R4,A
  3681. MOV B,A
  3682. MUL AB
  3683. XCH A,R3
  3684. CLR C
  3685. SUBB A,R3
  3686. MOV R3,A
  3687. MOV A,B
  3688. XCH A,R2
  3689. SUBB A,R2
  3690. MOV R2,A
  3691. SQR4: SETB C
  3692. MOV A,R4
  3693. RLC A
  3694. MOV R6,A
  3695. CLR A
  3696. RLC A
  3697. MOV R5,A
  3698. MOV A,R3
  3699. SUBB A,R6
  3700. MOV B,A
  3701. MOV A,R2
  3702. SUBB A,R5
  3703. JC SQR5
  3704. INC R4
  3705. MOV R2,A
  3706. MOV R3,B
  3707. SJMP SQR4
  3708. SQR5: MOV A,R4
  3709. XCH A,R2
  3710. RRC A
  3711. MOV F0,C
  3712. MOV A,R3
  3713. MOV R5,A
  3714. MOV R4,#8
  3715. SQR6: CLR C
  3716. MOV A,R3
  3717. RLC A
  3718. MOV R3,A
  3719. CLR C
  3720. MOV A,R5
  3721. SUBB A,R2
  3722. JB F0,SQR7
  3723. JC SQR8
  3724. SQR7: MOV R5,A
  3725. INC R3
  3726. SQR8: CLR C
  3727. MOV A,R5
  3728. RLC A
  3729. MOV R5,A
  3730. MOV F0,C
  3731. DJNZ R4,SQR6
  3732. MOV A,R3 ;将平方根的尾数回传到[R0]中
  3733. MOV @R0,A
  3734. DEC R0
  3735. MOV A,R2
  3736. MOV @R0,A
  3737. SQR9: DEC R0 ;数据指针回归原位
  3738. CLR OV ;开方结果有效
  3739. RET
  3740. ;(18) 标号: FPLN 功能:浮点数多项式计算
  3741. ;入口条件:自变量在[R0]中,多项式系数在调用指令之后,以40H结束。
  3742. ;出口信息:OV=0时,结果仍在[R0]中,OV=1时,溢出。
  3743. ;影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 4字节
  3744. FPLN: POP DPH ;取出多项式系数存放地址
  3745. POP DPL
  3746. XCH A,R0 ;R0、R1交换角色,自变量在[R1]中
  3747. XCH A,R1
  3748. XCH A,R0
  3749. CLR A ;清第一工作区
  3750. MOV R2,A
  3751. MOV R3,A
  3752. MOV R4,A
  3753. CLR 1FH
  3754. PLN1: CLR A ;读取一个系数,并装入第二工作区
  3755. MOVC A,@A+DPTR
  3756. MOV C,ACC.7
  3757. MOV 1EH,C
  3758. MOV C,ACC.6
  3759. MOV ACC.7,C
  3760. MOV R5,A
  3761. INC DPTR
  3762. CLR A
  3763. MOVC A,@A+DPTR
  3764. MOV R6,A
  3765. INC DPTR
  3766. CLR A
  3767. MOVC A,@A+DPTR
  3768. MOV R7,A
  3769. INC DPTR ;指向下一个系数
  3770. MOV C,1EH ;比较两个数符
  3771. RRC A
  3772. XRL A,23H
  3773. RLC A
  3774. MOV F0,C ;保存比较结果
  3775. LCALL AS1 ;进行代数加法运算
  3776. CLR A ;读取下一个系数的第一个字节
  3777. MOVC A,@A+DPTR
  3778. CJNE A,#40H,PLN2;是结束标志吗?
  3779. XCH A,R0 ;运算结束,恢复R0、R1原来的角色
  3780. XCH A,R1
  3781. XCH A,R0
  3782. LCALL MOV0 ;将结果回传到[R0]中
  3783. CLR A
  3784. INC DPTR
  3785. JMP @A+DPTR ;返回主程序
  3786. PLN2: MOV A,@R1 ;比较自变量和中间结果的符号
  3787. XRL A,23H
  3788. RLC A
  3789. MOV 1FH,C ;保存比较结果
  3790. LCALL MUL0 ;进行乘法运算
  3791. SJMP PLN1 ;继续下一项运算
  3792. ;(19) 标号: FLOG 功能:以10为底的浮点对数函数
  3793. ;入口条件:操作数在[R0]中。
  3794. ;出口信息:OV=0时,结果仍在[R0]中,OV=1时,负数或零求对数出错。
  3795. ;影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:9字节
  3796. FLOG: LCALL FLN ;先以e为底求对数
  3797. JNB OV,LOG
  3798. RET ;如溢出则停止计算
  3799. LOG: MOV R5,#0FFH;系数0.43430(1/Ln10)
  3800. MOV R6,#0DEH
  3801. MOV R7,#5CH
  3802. LCALL MUL1 ;通过相乘来换底
  3803. LJMP MOV0 ;传回结果
  3804. ;(20) 标号: FLN 功能:以e为底的浮点对数函数
  3805. ;入口条件:操作数在[R0]中。
  3806. ;出口信息:OV=0时,结果仍在[R0]中,OV=1时,负数或零求对数出错。
  3807. ;影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 7字节
  3808. FLN: LCALL MVR0 ;将[R0]传送到第一工作区
  3809. JB 1FH,LNOV;负数或零求对数,出错
  3810. MOV A,R3
  3811. ORL A,R4
  3812. JNZ LN0
  3813. LNOV: SETB OV
  3814. RET
  3815. LN0: CLR C
  3816. LCALL RL1 ;左规一次
  3817. CLR A
  3818. XCH A,R2 ;保存原阶码,清零工作区的阶码
  3819. PUSH ACC
  3820. LCALL RLN ;规格化
  3821. LCALL MOV0 ;回传
  3822. LCALL FPLN ;用多项式计算尾数的对数
  3823. DB 7BH,0F4H,30H;0.029808
  3824. DB 0FEH,85H,13H;-0.12996
  3825. DB 7FH,91H,51H;0.28382
  3826. DB 0FFH,0FAH,0BAH;-0.4897
  3827. DB 0,0FFH,0CAH;0.99918
  3828. DB 70H,0C0H,0;1.1442×10-5
  3829. DB 40H ;结束
  3830. POP ACC ;取出原阶码
  3831. JNZ LN1
  3832. RET ;如为零,则结束
  3833. LN1: CLR 1EH ;清第二区数符
  3834. MOV C,ACC.7
  3835. MOV F0,C ;保存阶符
  3836. JNC LN2
  3837. CPL A ;当阶码为负时,求其绝对值
  3838. INC A
  3839. LN2: MOV R2,A ;阶码的绝对值乘以0.69315
  3840. MOV B,#72H
  3841. MUL AB
  3842. XCH A,R2
  3843. MOV R7,B
  3844. MOV B,#0B1H
  3845. MUL AB
  3846. ADD A,R7
  3847. MOV R7,A ;乘积的尾数在R6R7R2中
  3848. CLR A
  3849. ADDC A,B
  3850. MOV R6,A
  3851. MOV R5,#8 ;乘积的阶码初始化(整数部分为一字节)
  3852. LN3: JB ACC.7,LN4;乘积格式化
  3853. MOV A,R2
  3854. RLC A
  3855. MOV R2,A
  3856. MOV A,R7
  3857. RLC A
  3858. MOV R7,A
  3859. MOV A,R6
  3860. RLC A
  3861. MOV R6,A
  3862. DEC R5
  3863. SJMP LN3
  3864. LN4: MOV C,F0 ;取出阶符,作为乘积的数符
  3865. MOV ACC.7,C
  3866. LJMP ASN ;与尾数的对数合并,得原操作数的对数
  3867. ;(21) 标号: FE10 功能:以10为底的浮点指数函数
  3868. ;入口条件:操作数在[R0]中。
  3869. ;出口信息:OV=0时,结果仍在[R0]中,OV=1时,溢出。
  3870. ;影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节
  3871. FE10: MOV R5,#2 ;加权系数为3.3219(Log210)
  3872. MOV R6,#0D4H
  3873. MOV R7,#9AH
  3874. SJMP EXP ;先进行加权运算,后以2为底统一求幂
  3875. ;(22) 标号: FEXP 功能:以e为底的浮点指数函数
  3876. ;入口条件:操作数在[R0]中。
  3877. ;出口信息:OV=0时,结果仍在[R0]中,OV=1时,溢出。
  3878. ;影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节
  3879. FEXP: MOV R5,#1 ;加权系数为1.44272(Lng2e)
  3880. MOV R6,#0B8H
  3881. MOV R7,#0ABH
  3882. EXP: CLR 1EH ;加权系数为正数
  3883. LCALL MVR0 ;将[R0]传送到第一工作区
  3884. LCALL MUL1 ;进行加权运算
  3885. SJMP E20 ;以2为底统一求幂
  3886. ;(23) 标号: FE2 功能:以2为底的浮点指数函数
  3887. ;入口条件:操作数在[R0]中。
  3888. ;出口信息:OV=0时,结果仍在[R0]中,OV=1时,溢出。
  3889. ;影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节
  3890. FE2: LCALL MVR0 ;将[R0]传送到第一工作区
  3891. E20: MOV A,R3
  3892. ORL A,R4
  3893. JZ EXP1 ;尾数为零
  3894. MOV A,R2
  3895. JB ACC.7,EXP2;阶符为负?
  3896. SETB C
  3897. SUBB A,#6 ;阶码大于6否?
  3898. JC EXP2
  3899. JB 1FH,EXP0;数符为负否?
  3900. MOV @R0,#3FH;正指数过大,幂溢出
  3901. INC R0
  3902. MOV @R0,#0FFH
  3903. INC R0
  3904. MOV @R0,#0FFH
  3905. DEC R0
  3906. DEC R0
  3907. SETB OV
  3908. RET
  3909. EXP0: MOV @R0,#41H;负指数过大,幂下溢,清零处理
  3910. CLR A
  3911. INC R0
  3912. MOV @R0,A
  3913. INC R0
  3914. MOV @R0,A
  3915. DEC R0
  3916. DEC R0
  3917. CLR OV
  3918. RET
  3919. EXP1: MOV @R0,#1 ;指数为零,幂为1.00
  3920. INC R0
  3921. MOV @R0,#80H
  3922. INC R0
  3923. MOV @R0,#0
  3924. DEC R0
  3925. DEC R0
  3926. CLR OV
  3927. RET
  3928. EXP2: MOV A,R2 ;将指数复制到第二工作区
  3929. MOV R5,A
  3930. MOV A,R3
  3931. MOV R6,A
  3932. MOV A,R4
  3933. MOV R7,A
  3934. MOV C,1FH
  3935. MOV 1EH,C
  3936. LCALL INT ;对第一区取整
  3937. MOV A,R3
  3938. JZ EXP4
  3939. EXP3: CLR C ;使尾数高字节R3对应一个字节整数
  3940. RRC A
  3941. INC R2
  3942. CJNE R2,#8,EXP3
  3943. EXP4: MOV R3,A
  3944. JNB 1FH,EXP5
  3945. CPL A ;并用补码表示
  3946. INC A
  3947. EXP5: PUSH ACC ;暂时保存之
  3948. LCALL RLN ;重新规格化
  3949. CPL 1FH
  3950. SETB F0
  3951. LCALL AS1 ;求指数的小数部分
  3952. LCALL MOV0 ;回传指数的小数部分
  3953. LCALL FPLN ;通过多项式计算指数的小数部分的幂
  3954. DB 77H,0B1H,0C9H;1.3564×10-3
  3955. DB 7AH,0A1H,68H;9.8514×10-3
  3956. DB 7CH,0E3H,4FH;0.055495
  3957. DB 7EH,0F5H,0E7H;0.24014
  3958. DB 0,0B1H,72H;0.69315
  3959. DB 1,80H,0 ;1.00000
  3960. DB 40H ;结束
  3961. POP ACC ;取出指数的整数部分
  3962. ADD A,R2 ;按补码加到幂的阶码上
  3963. MOV R2,A
  3964. CLR 1FH ;幂的符号为正
  3965. LJMP MOV0 ;将幂传回[R0]中
  3966. ;(24)标号: DTOF 功能:双字节十六进制定点数转换成格式化浮点数
  3967. ;入口条件:双字节定点数的绝对值在[R0]中,数符在位1FH中,整数部分的位数在A中。
  3968. ;出口信息:转换成格式化浮点数在[R0]中(三字节)。
  3969. ;影响资源:PSW、A、R2、R3、R4、位1FH 堆栈需求: 6字节
  3970. DTOF: MOV R2,A ;按整数的位数初始化阶码
  3971. MOV A,@R0 ;将定点数作尾数
  3972. MOV R3,A
  3973. INC R0
  3974. MOV A,@R0
  3975. MOV R4,A
  3976. DEC R0
  3977. LCALL RLN ;进行规格化
  3978. LJMP MOV0 ;传送结果到[R0]中
  3979. ……………………

  3980. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码



评分

参与人数 3黑币 +56 收起 理由
345681892 + 5 很给力!
mi30806024 + 1 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:345799 发表于 2018-6-18 22:40 | 显示全部楼层
挺好用
回复

使用道具 举报

ID:20672 发表于 2018-8-1 19:42 | 显示全部楼层
谢谢分享~~~
回复

使用道具 举报

ID:34017 发表于 2018-11-29 00:08 | 显示全部楼层
这个非常不错,不过我记得原来有一个非常全的子程序集
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表