在20H后放入10个字节,用51汇编,找出重复出现频率最高的字节

在 20H 后放入 10 个字节数据,用 51 汇编语言编程,找出重复出现频率最高的字节。
例如:放入12、23、32、32、32、43、32、56、56、35,程序能够输出 32。
问题补充:很感谢“做而论道”的回答,请问这个 7EH 和 7FH 是干什么用的?
悬赏分:50 - 解决时间:2010-1-31 14:55
;------------------------------------------------
最佳答案:

程序说明:
先从20H开始查找数据,把首次出现的数据存放到40H开始的单元,并在60H开始的单元,存放该数据的个数;如果数据是重复出现的,就将其个数加一。
之后从60H单元开始找最大值的位置,找到后,再从40H开始找到对应出现次数最多的数据,送到A及P1。

程序已经经过了验证,符合要求,如下:
;-------------------------------------------------
        ORG  0000H
        MOV  20H, #12H        ;准备10个原始数据.
        MOV  21H, #23H
        MOV  22H, #32H
        MOV  23H, #32H
        MOV  24H, #32H
        MOV  25H, #43H
        MOV  26H, #32H
        MOV  27H, #56H
        MOV  28H, #56H
        MOV  29H, #35H
        CLR  A
        MOV  R0, #40H         ;其它空间清零
QING_0:
        MOV  @R0, A
        INC  R0
        CJNE R0, #80H, QING_0
;------------------------------------------下面就是查找出现频率最高的程序
        MOV  R0, #20H        ;原始数据起始地址.
        MOV  R1, #40H        ;筛选后的数据起始地址.
        MOV  7FH, #1         ;现筛选出来1个数据: 00H
        MOV  7EH, 7FH
        INC  7EH
        MOV  R7, #10         ;共有10个未知数据,(最多可以有32个)
;---------------------------
BBB:    MOV  A,  @R0         ;取出未知数据.
        MOV  R1, #40H        ;从头 和已筛选出的比较.
WWW:    MOV  B,  @R1
        CJNE A, B, CCC        ;不同就比较下一个.
RRR:    MOV  A,  R1          ;相同则个数加一.
        ADD  A,  #20H        ;在60H以上的位置加一
        MOV  R1, A
        INC  @R1
        INC  R0              ;转到下一个未知数据.
        MOV  7EH, 7FH
        INC  7EH
        DJNZ R7, BBB         ;循环查找10个数据
;---------------------------
        SJMP EEE             ;查找数据结束
;-----------------------------------------------------
CCC:    INC  R1
        DJNZ 7EH, WWW        ;按照筛选出来的数据个数循环.
;-----------------------------------------------------
        MOV  A,  #40H        ;没有找到,那就存入这个数据.
        ADD  A,  7FH
        MOV  R1, A           ;计算出新数据应该存放的地址.
        MOV  A,  @R0
        MOV  @R1, A          ;存放.
        INC  7FH             ;已知数据个数加一.
        MOV  7EH, 7FH
        INC  7EH
        SJMP RRR
;-----------------------------------------------------
EEE:                         ;从筛选后的个数中找最多数据的地址.
        MOV  7EH, #0
        MOV  R0, #60H
YYY:    MOV  A,  @R0
        CJNE A, 7EH, $ + 3
        JC   TTT
        MOV  7EH, A
        MOV  B,  R0          ;保存地址
TTT:    INC  R0
        DJNZ 7FH, YYY        ;按照筛选出来的数据个数循环.
;-----------------------------------------------------
        MOV  A, B            ;根据这个地址
        CLR  C
        SUBB A, #20H
        MOV  R0, A
        MOV  A, @R0          ;再找到数据.
        MOV  P1, A           ;输出到P1

        SJMP $
END
;------------------------------------------------------
程序用keil仿真运行后,RAM空间的数据和输出,可见下图。

在20H后放入10个字节,用51汇编,找出重复出现频率最高的字节 - 非著名博主 - 电子信息角落
;------------------------------------------------------
对补充提问的说明:7FH 7EH,是51单片机片内RAM的最后两个单元。
对筛选出来的数据,需要统计个数,进行循环处理,还需要控制循环次数,它们就担任了这个任务。
用Rn也可,但是涉及互相传送的时候,不方便;7FH 7EH,基本是空闲的,可以利用。
;------------------------------------------------------
参考资料:原创
回答者: 做而论道 - 十二级   2010-1-31 08:39
提问者对于答案的评价:真是太感谢您了
原题网址:http://zhidao.baidu.com/question/135656256.html
;------------------------------------------------------
后记:

本程序,可算是个较大的程序,提问者利用百度Hi多次提出询问和新的要求,反复讨论了好几天。
提问者终于弄明白了本程序的要点,使用方法、改变参数的方法。
经过了提问者的确认,做而论道才在网页上公布了双方认可的最终版本,并由对方选为最佳答案。
;------------------------------------------------------

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一种可能的解决方案: ``` mov r0, #20H ; 将内部RAM起始地址为20H的存储单元地址存入寄存器r0 mov r1, #30H ; 将内部RAM起始地址为30H的存储单元地址存入寄存器r1 ; 从内存中读取两个三字节无符号 mov a, @r0 ; 读取第一个的低字节,存入累加器a inc r0 ; 内存地址加1,指向第一个的中字节 mov b, @r0 ; 读取第一个的中字节,存入累加器b inc r0 ; 内存地址加1,指向第一个的高字节 mov r2, @r0 ; 读取第一个的高字节,存入寄存器r2 mov c, @r1 ; 读取第二个的低字节,存入累加器c inc r1 ; 内存地址加1,指向第二个的中字节 mov d, @r1 ; 读取第二个的中字节,存入累加器d inc r1 ; 内存地址加1,指向第二个的高字节 mov r3, @r1 ; 读取第二个的高字节,存入寄存器r3 ; 从高位到低位逐位相减 subb a, c ; 低字节相减,结果存回累加器a subb b, d ; 中字节相减,结果存回累加器b subb r2, r3 ; 高字节相减,结果存回寄存器r2 ; 结果存回内存 mov @20H, a ; 将结果的低字节存回内存 inc r0 ; 内存地址加1,指向结果的中字节 mov @r0, b ; 将结果的中字节存回内存 inc r0 ; 内存地址加1,指向结果的高字节 mov @r0, r2 ; 将结果的高字节存回内存 ``` 需要注意的是,这里的相减是指无符号相减,因此如果被减小于减,结果会是一个带有溢出标志的负。因此,在实际应用中需要根据需要进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值