zoukankan      html  css  js  c++  java
  • 查看51汇编,解决奇怪的问题

    对于51,多数人觉得很简单,但是大家却极容易犯的错误就是忽略了编译器。Keil是无疑对于51系列最好的编译器了,但是它不是智能的(编译原理)。

    在我再次拾起51时(此时是为了学习ucos在51上的移植,很有意思),我试着深入去了解一些C程序在进行编译后KEIL为我们做的工作到底是怎样的,当然这部分是很难了解的很清楚的,要相当多的经验与教训.

    今天在试着写一个程序的时候,发现了如下的问题:
      今天写的对键盘的扫描的小程序中,刚开始我是这样写的:
        INT8U Keycheck(){
         INT8U Keytmp;
         P2 = 0xFF;
         Keytmp = P2;
         //Keytmp = P2&0x0f;
         if(P2!=Keytmp){
           switch(Keytmp){
       case 0xFE : returnkey = 0x01;break;
       case 0xFD : returnkey = 0x02;break;
       case 0xFB : returnkey = 0x03;break;
       case 0xF7 : returnkey = 0x04;break;
      }
        }

         return returnkey;
       }

    但是仿真的时候却不对(没有加去抖动部分),查看汇编代码后发现如下的结果
      C:0x008F    75A0FF   MOV      P2(0xA0),#0xFF
        21:      Keytmp = P2;
        22:    //Keytmp = P2&0x0f;
      C:0x0092    AFA0     MOV      R7,P2(0xA0)
        23:    if(P2!=Keytmp){
      C:0x0094    E5A0     MOV      A,P2(0xA0)
      C:0x0096    6F       XRL      A,R7
      C:0x0097    6022     JZ       C:00BB
        24:      switch(Keytmp){  省略

       由生成的汇编代码中可以看出:XRL A,R7 就是对if(P2!=Keytmp)KEIL的翻译,但是此时的A和R7其实是相等的,也就是无法判断出按键的按下,实际仿真时可以发现极少的情况下能判断出按键的按下(偶尔有出现过)。

     由上我将程序改成了如下(即将if里面的语句进行了调转)
        此时的汇编程序为:
        C:0x008F    75A0FF   MOV      P2(0xA0),#0xFF
        21:    Keytmp = P2;
        22:    //Keytmp = P2&0x0f;
        C:0x0092    AFA0     MOV      R7,P2(0xA0)
        23:    if(Keytmp!=P2){
        C:0x0094    EF       MOV      A,R7
        C:0x0095    65A0     XRL      A,P2(0xA0)
        C:0x0097    6022     JZ       C:00BB
        24:      switch(Keytmp){

      但是此时的汇编代码KEIL并没有做太大的改变,显然仿真的效果仍然不是很好,不能很好的检测到按键

      此时再将程序改为如下形式:
      INT8U Keycheck(){
       INT8U Keytmp;
       P2 = 0xFF;
       //Keytmp = P2;
       Keytmp = P2&0x0f;
       if(Keytmp!=0x0f){
         switch(Keytmp){
       case 0x0E : returnkey = 0x01;break;
       case 0x0D : returnkey = 0x02;break;
       case 0x0B : returnkey = 0x03;break;
       case 0x07 : returnkey = 0x04;break;
      }
        }


        return returnkey;
      }

    此时在看汇编代码的时候发现KEIL给了较大的改变:
      C:0x008F    75A0FF   MOV      P2(0xA0),#0xFF
        22:    Keytmp = P2&0x0f;
      C:0x0092    E5A0     MOV      A,P2(0xA0)
      C:0x0094    540F     ANL      A,#0x0F
      C:0x0096    FF       MOV      R7,A
        23:    if(Keytmp!=0x0f){
      C:0x0097    640F     XRL      A,#0x0F
      C:0x0099    6022     JZ       C:00BD

    此时对简单的汇编语句进行分析可以看到就不会出现上面的情况,此时通过仿真就能很好的进行按键的检测,不会出现错误(没加上去抖动部分程序)
     

  • 相关阅读:
    ELK+FileBeat 开源日志分析系统搭建-Centos7.8
    ORACLE转换时间戳方法(1546272000)
    由Swap故障引起的ORA-01034: ORACLE not available ORA-27102: out of memory 问题
    数据库设计规范
    数据库字段备注信息声明语法 CDL (Comment Declaration Language)
    渐进式可扩展数据库模型(Progressive Extensible Database Model, pedm)
    使用 ES6 的 Promise 对象和 Html5 的 Dialog 元素,模拟 JS 的 alert, confirm, prompt 方法的阻断执行功能。
    在sed中引入shell变量的四种方法
    参考文献中的[EB/OL]表示什么含义?
    优秀看图软件 XnViewMP v0.97.1 / XnView v2.49.4 Classic
  • 原文地址:https://www.cnblogs.com/zxqwolf/p/2840801.html
Copyright © 2011-2022 走看看