找回密码
 立即注册
楼主: 道清

双字节除法运算汇编程序请高手指导

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-08-28 05:43:12
已绑定手机

3

主题

28

回帖

93

积分

注册会员

积分
93
发表于 2025-8-26 08:38:35 | 显示全部楼层
其他我多看的懂,也知道逻辑。就是这部分的逻辑我想不通,方便的话能详细解释吗?
谢谢



PROCESS_HIGH:
                MOV     A, R6
        JZ      PROCESS_LOW  ; 高8位为0且低8位<10,处理最后一位
                ; 高8位减1,补充十位25和个位6
        DEC     R6
        
                MOV         A, #6
                ADD     A, 34H
        MOV     34H, A
               
                MOV         A, #25
                ADD     A, 33H
        MOV     33H, A
               
                ; 处理各数位进位
        LCALL   HANDLE_CARRY
        SJMP    PROCESS_HIGH    ; 再次检查高8位        这条好像是多余的吧

PROCESS_LOW:

        ; 低8位处理
        MOV     A, R7
        MOV     B, #10
        DIV     AB           ; 仅对低8位使用DIV
        MOV     R7, A        ; 保存商到低8位
        MOV     A, B         ; 余数作为当前十进制位
        
        ; 将余数累加到结果缓冲区的个位
        ADD     A, 34H
        MOV     34H, A
        
                ; 将商累加到结果缓冲区的十位
                MOV     A,R7
                ADD     A, 33H
        MOV     33H, A
                MOV     R7,#0
               
        ; 处理各数位进位
        LCALL   HANDLE_CARRY
               
               
                RET


还有程序中的这条  ( SJMP    PROCESS_HIGH    ; 再次检查高8位)        这条好像是多余的吧

点评

PROCESS_HIGH是循环,每次高位字节减一,拿去补充十位和个位,高字节的1分拆成25*10+6,直到减完高位字节再去处理低位。 PROCESS_LOW只执行一次,把低字节刷入十进制缓冲区。  详情 回复 发表于 2025-8-26 09:01
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:287
  • 最近打卡:2025-09-03 08:55:47
已绑定手机

80

主题

3032

回帖

6445

积分

荣誉版主

无情的代码机器

积分
6445
发表于 2025-8-26 09:01:16 | 显示全部楼层
道*** 发表于 2025-8-26 08:38
其他我多看的懂,也知道逻辑。就是这部分的逻辑我想不通,方便的话能详细解释吗?
谢谢

PROCESS_HIGH是循环,每次高位字节减一,拿去补充十位和个位,高字节的1分拆成25*10+6,直到减完高位字节再去处理低位。


PROCESS_LOW只执行一次,把低字节刷入十进制缓冲区。



“JZ      PROCESS_LOW  ; 高8位为0且低8位<10,处理最后一位” 这条注释改为 “高8位为0,跳转处理低八位”
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:123
  • 最近打卡:2025-09-03 08:09:51
已绑定手机

17

主题

483

回帖

1589

积分

金牌会员

积分
1589
发表于 2025-8-26 09:15:59 | 显示全部楼层
道*** 发表于 2025-8-25 20:12
非常感谢您的帮助,从程序逻辑上我有启发,如果12345这个数是事先就是知道的,123和45分开存放是这个程序 ...

网上搜索一下,需要循环比较
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-08-28 05:43:12
已绑定手机

3

主题

28

回帖

93

积分

注册会员

积分
93
发表于 2025-8-26 11:29:14 | 显示全部楼层
erci*** 发表于 2025-8-26 09:01
PROCESS_HIGH是循环,每次高位字节减一,拿去补充十位和个位,高字节的1分拆成25*10+6,直到减完高位字节 ...

看来我是想不通这个题目了,越看越不懂,等会我吧我的程序整理一下,麻烦您帮我看看,谢谢
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-08-28 05:43:12
已绑定手机

3

主题

28

回帖

93

积分

注册会员

积分
93
发表于 2025-8-26 12:20:46 | 显示全部楼层
erci*** 发表于 2025-8-26 09:01
PROCESS_HIGH是循环,每次高位字节减一,拿去补充十位和个位,高字节的1分拆成25*10+6,直到减完高位字节 ...

        SMG1       EQU      P1.0    ;数码管  1
         SMG2       EQU      P1.1    ;数码管  2
         SMG3       EQU      P1.3    ;数码管  3
         SMG4       EQU      P1.2    ;数码管  4
         ;数据       EQU      P3.0    ;164
         ;时间       EQU      P3.1    ;164
         FMQ         EQU      P3.4   ;蜂鸣器
         GNAN        EQU      P3.0   ;按下启动两只电机
         ANB         EQU      P3.1   ;按钮B
         ANA         EQU      P3.2   ;按钮A
         JDQ         EQU      P3.5    ;送料电机
         BJD         EQU      P1.6   ;数量到报警灯
         P1K         EQU      0EEH
         P2K         EQU      0EDH
         P3K         EQU      0ECH
         DLA         EQU      0EFH
         ORG         00H
         JMP         QQ

;------FH1------程序运行一次无返回-----------

;;----程序开始-------------
QQ:    CLR    FMQ     ;关闭蜂鸣器


        MOV     DPTR,#12345
        CALL    MAIN
       ;这四行的意思是把您分解出来的数 放到我显示的H里,我再调用显示程序,依次一位的显示  
        MOV     38H,30H
        MOV     35H,31H
        MOV     36H,32H
        MOV     37H,33H
C1:     CALL     XS        ;调用显示程序
       JMP    C1           ;回调用显示程序
;-------------------------------------------------------------------------
;=================您写的程序开始=====我复制的========================
MAIN:   MOV     R6, DPH    ; 高8位示例值
        MOV     R7, DPL    ; 低8位示例值
        LCALL   HEX2DEC      ; 调用转换子程序
;STOP:   SJMP    STOP         ; 程序暂停
        RET
; 转换子程序:R6R7 -> 30H-34H
HEX2DEC:
        MOV     30H, #0      ; 初始化5字节缓冲区(万位)
        MOV     31H, #0      ; 千位
        MOV     32H, #0      ; 百位
        MOV     33H, #0      ; 十位
        MOV     34H, #0      ; 个位

        LCALL PROCESS_HIGH

        RET                  ; 转换完成返回


; 十进位处理子程序
HANDLE_CARRY:
        ; 处理个位进位到十位
        MOV     A, 34H
        MOV     B, #10
        DIV     AB           ; A=商(进位), B=余数(个位)
        MOV     34H, B       ; 保存个位
        MOV     R0, A        ; 暂存进位值

        ; 处理十位进位到百位 - 累加进位
        MOV     A, 33H
        ADD     A, R0        ; 原有十位值 + 进位
        MOV     B, #10
        DIV     AB           ; A=商(进位), B=余数(十位)
        MOV     33H, B       ; 保存十位
        MOV     R0, A        ; 更新进位值

        ; 处理百位进位到千位 - 累加进位
        MOV     A, 32H
        ADD     A, R0        ; 原有百位值 + 进位
        MOV     B, #10
        DIV     AB           ; A=商(进位), B=余数(百位)
        MOV     32H, B       ; 保存百位
        MOV     R0, A        ; 更新进位值

        ; 处理千位进位到万位 - 累加进位
        MOV     A, 31H
        ADD     A, R0        ; 原有千位值 + 进位
        MOV     B, #10
        DIV     AB           ; A=商(进位), B=余数(千位)
        MOV     31H, B       ; 保存千位
        MOV     R0, A        ; 更新进位值

        ; 处理万位进位
        MOV     A, 30H
        ADD     A, R0        ; 原有万位值 + 进位
        MOV     30H, A       ; 保存万位(最多为65535,不会超过10)

        RET

PROCESS_HIGH:
                MOV     A, R6
                JZ      PROCESS_LOW  ; 高8位为0且低8位<10,处理最后一位
                ; 高8位减1,补充十位25和个位6
                DEC     R6

                MOV         A, #6
                ADD     A, 34H
                MOV     34H, A

                MOV         A, #25
                ADD     A, 33H
                MOV     33H, A

                ; 处理各数位进位
                LCALL   HANDLE_CARRY
                SJMP    PROCESS_HIGH    ; 再次检查高8位

PROCESS_LOW:

        ; 低8位处理
                MOV     A, R7
                MOV     B, #10
                DIV     AB           ; 仅对低8位使用DIV
                MOV     R7, A        ; 保存商到低8位
                MOV     A, B         ; 余数作为当前十进制位

        ; 将余数累加到结果缓冲区的个位
                ADD     A, 34H
                MOV     34H, A

                ; 将商累加到结果缓冲区的十位
                MOV     A,R7
                ADD     A, 33H
                MOV     33H, A
                MOV     R7,#0

        ; 处理各数位进位
                LCALL   HANDLE_CARRY


                RET
;=================您写的程序结束=====我复制的==============================================================================================================

    ;----74164显示----过程是把放在35H.36H。37H.38H,里的数字一次一位的送去显示在数码管上-----------------
    ;目前显示只有四位,只要能显示1234或2345,我再自己加一位

XS:     MOV      A,36H     ;把分解出来的放在36H里的数送到A里
        CALL     MB        ;调用码表   
        CALL     L164      ;调用164控制子程序
        CLR      SMG3      ;让控住脚接通负极,让这位数码管灯亮
        CALL     T2MS      ;让数码管延时点亮20毫秒
        SETB     SMG3      ;让控住脚接通正极,让这位数码管灯灭
        ;--------------------下面依次;亮;灭。数码管---四位共阴数码管-----我就不依次备注了-
        MOV      A,37H
        CALL     MB
        CALL     L164
        CLR      SMG4
        CALL     T2MS
        SETB     SMG4
        ;-------------------------
        MOV      A,35H
        CALL     MB
XSD:    CALL     L164
        CLR      SMG2
        CALL     T2MS
        SETB     SMG2
        ;-----------------------------
        MOV      A,38H
        CALL     MB
XSD1:   CALL     L164
        CLR      SMG1
        CALL     T2MS
        SETB     SMG1

        RET

;================L164=========================
L164:      MOV        65H,#08
           SETB       P3.3
           NOP
LOOP_0:    CLR        P3.3
           NOP
           RRC        A
           NOP
           MOV        P3.7,C
           NOP
           NOP
           SETB       P3.3
           NOP
           NOP
           NOP
           NOP
           DJNZ       65H,LOOP_0
           RET

;===========2MS延时===================
T2MS:       MOV       60H,#03H      ;08
D2MS_0:     MOV       61H,#03H      ;40
D2MS_1:     NOP
            DJNZ      61H,D2MS_1
            DJNZ      60H,D2MS_0
            NOP
            RET
;=============段码表  ===========================
MB:       INC       A
          MOVC      A,@A+PC
          RET
          DB        0EEH,22H,0BCH,0B6H,72H,0D6H,0DEH,0A2H,0FEH,0F6H,0FAH,5EH,0CCH,3EH,0DCH,0D8H,0CEH,7AH,8H,2EH,7CH,4CH,9AH,1AH,1EH,0F8H,0F2H,18H,0D2H,5CH,6EH,70H,8EH,74H,76H,94H,00H,4H,14H,94H,     ; 灯不亮是36  ;一点是37
          RET                                                                                                                                                                                          ;二点是38    ;三点是39
;=================================================
;--------------传感器AD信号-------------------
STCAD:
            MOV     0BCH,#11101100B          ;P1.4做传感器AD
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
WAD5:       MOV     A,0BCH
            JNB     ACC.4,WAD5
            MOV     A,0BDH
            MOV     10H,A
            SETB         P1.4

            RET
;--------------延时AD信号-------------------
STCAD1:
            MOV     0BCH,#11101101B          ;P1.5做延时AD
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
WAF5:       MOV     A,0BCH
            JNB     ACC.4,WAF5
            MOV     A,0BDH
            SUBB    A,#85
            JNC      AF1
            MOV      A,#0
            NOP
AF1:        NOP
            SETB         P1.5
            RET

;=============蜂鸣器响壹声===========================
FMQKJ:      SETB       FMQ
            MOV        R1,#255
Z1:         CALL       XS
            DJNZ       R1,Z1

            CLR        FMQ
            MOV        R1,#255
Z2:         CALL       XS
            DJNZ       R1,Z2


            RET

;=========读第X扇区============
       ;  MOV     DPTR,#000H
DU:         MOV     0C7H,#10000010B    ;设置反映时间
            MOV     0C5H,#1       ;1是读的指令
            MOV     0C3H,DPH
            MOV     0C4H,DPL

            MOV     0C6H,#5AH      ;0C6H必须做2个动作
            MOV     0C6H,#0A5H     ;0C6H必须做2个动作
            NOP
            MOV     A,0C2H         ;读出来的数据放在0C2H
            NOP

            RET
    ;=============擦除===========
        ;    MOV     DPTR,#000H
CHA:        MOV     0C7H,#10000010B
            MOV     0C5H,#3
            MOV     0C3H,DPH
            MOV     0C4H,DPL
            MOV     0C6H,#5AH
            MOV     0C6H,#0A5H
            NOP

            RET
         ;=============写============
         ;    MOV     DPTR,#000H
XIE:        MOV     0C7H,#10000010B
            MOV     0C5H,#2
            MOV     0C3H,DPH
            MOV     0C4H,DPL

            MOV     0C2H,A         ;数据放在0C2H,写进去
            MOV     0C6H,#5AH
            MOV     0C6H,#0A5H
            NOP
            CALL    FZWCZ
             RET

;=============================================
;===========单片机片内储存防止误抄作============
FZWCZ:        MOV     07CH,#0
              MOV     0C5H,#0
              MOV     0C6H,#0
              MOV     0C3H,#80H
              MOV     0C4H,#0
              RET
END



点评

看到一些语法问题, MAIN一般是程序入口,代码库当函数用建议另起各名字,并且用CALL调用MAIN没加RET,原程序是main执行完无限循环停止程序。 还有比如CALL XS,CALL对应的代码块一般用RET结束,或者JMP去别的有R  详情 回复 发表于 2025-8-26 14:15
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:287
  • 最近打卡:2025-09-03 08:55:47
已绑定手机

80

主题

3032

回帖

6445

积分

荣誉版主

无情的代码机器

积分
6445
发表于 2025-8-26 14:15:53 | 显示全部楼层
道*** 发表于 2025-8-26 12:20
SMG1       EQU      P1.0    ;数码管  1
         SMG2       EQU      P1.1    ;数码管  2
    ...

看到一些语法问题,
MAIN一般是程序入口,代码库当函数用建议另起各名字,并且用CALL调用MAIN没加RET,原程序是main执行完无限循环停止程序。
还有比如CALL     XS,CALL对应的代码块一般用RET结束,或者JMP去别的有RET结束的代码块,这个检查下哈



另外这个程序调试建议分两部分独立调试再组合
1.给个固定值数码管能正常显示
2.双字节转十进制缓存,这部分在仿真里就可以验证
3.再是联调

截图202508261412498046.jpg

三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-08-28 05:43:12
已绑定手机

3

主题

28

回帖

93

积分

注册会员

积分
93
发表于 2025-8-26 16:40:40 | 显示全部楼层
erci*** 发表于 2025-8-26 14:15
看到一些语法问题,
MAIN一般是程序入口,代码库当函数用建议另起各名字,并且用CALL调用MAIN没加RET,原 ...

我的程序韦福运行了,没有报错的,
但你的图片里的,好像有不一样,不懂
我们还是讨论现存的程序好了,以免大家说跑偏了。
谢谢

点评

我上面发的不一定编译时报错,运行时可能异常或跑飞。 有CALL就要有RET,不明白建议可以看下陈桂友老师的汇编课程: 陈桂友老师-STC单片机教学视频 国芯人工智能技术交流网站 - AI32位8051交流社区 先把上面问题  详情 回复 发表于 2025-8-26 17:19
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:287
  • 最近打卡:2025-09-03 08:55:47
已绑定手机

80

主题

3032

回帖

6445

积分

荣誉版主

无情的代码机器

积分
6445
发表于 2025-8-26 17:19:38 | 显示全部楼层
道*** 发表于 2025-8-26 16:40
我的程序韦福运行了,没有报错的,
但你的图片里的,好像有不一样,不懂
我们还是讨论现存的程序好了,以 ...


我上面发的不一定编译时报错,运行时可能异常或跑飞。

有CALL就要有RET,不明白建议可以看下陈桂友老师的汇编课程:
陈桂友老师-STC单片机教学视频 国芯人工智能技术交流网站 - AI32位8051交流社区


先把上面问题搞明白,代码修改后再试下,然后讨论现存程序要发细节:

第一步只调试数码管,验证情况怎么样,缓冲区固定值4567能显示4567吗
第二步仿真 算法,输入什么,输出是什么,验证情况怎么样
第三步联调,现在什么问题,什么现象,


三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-08-28 05:43:12
已绑定手机

3

主题

28

回帖

93

积分

注册会员

积分
93
发表于 2025-8-26 19:37:30 | 显示全部楼层
道*** 发表于 2025-8-26 16:40
我的程序韦福运行了,没有报错的,
但你的图片里的,好像有不一样,不懂
我们还是讨论现存的程序好了,以 ...

感谢,加   RET后就显示1234了

谢谢

我再试试其他
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-08-28 05:43:12
已绑定手机

3

主题

28

回帖

93

积分

注册会员

积分
93
发表于 2025-8-26 19:42:19 | 显示全部楼层
erci*** 发表于 2025-8-26 17:19
我上面发的不一定编译时报错,运行时可能异常或跑飞。

有CALL就要有RET,不明白建议可以看下陈桂友老师 ...

反复测试多成功了,感谢
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-9-3 09:02 , Processed in 0.133624 second(s), 106 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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