设为首页收藏本站淘宝杂货铺

从F到0 - From F to 0

 找回密码
 注册已关闭
搜索
查看: 1553|回复: 1
收起左侧

基于C51(STC)单片机XRAM(XDATA)的校验功能 防止程序跑飞以及MOVX寻址的RAM被非法篡改

[复制链接]
发表于 2019-9-4 17:45:09 | 显示全部楼层 |阅读模式
硬件连接:P3口连接8个LED与VCC(共阳连接)。
校验正确:演示二进制累加。
校验错误:8个灯一起闪烁。
只要MOVX指令1个字节读写出错,就会校验错误。



  1. /*
  2. 使用本程序严禁将其他变量分配到XDATA空间
  3. 必须使用 read_xram() 和 write_xram() 函数读写,否则将出错。
  4. */
  5. #include "reg51.h"
  6. #include "absacc.h"
  7. #include "intrins.h"

  8. #define U8 unsigned char
  9. #define U16 unsigned int
  10. #define U32 unsigned long
  11. #define max_xram_address 16383        //XRAM最大可访问地址(总容量-1 不同型号会有不同)
  12. U32 xram_check=0;                //XDATA校验和(写入数值时改)
  13. U8 xram_xor = 0;                //XRAM异或校验
  14. /*
  15. 通过16位地址和8位值返回一个1字节固定散列值
  16. */
  17. U8 hash_xram(U16 address,U8 value){
  18.         return _irol_(address*value,value&15);
  19. }

  20. /*
  21. 读XDATA函数(参数1:地址) 返回数值
  22. */
  23. U8 read_xram(U16 address){       
  24.         if(address > max_xram_address) return 0;
  25.         return XBYTE[address];

  26. }

  27. /*
  28. 写XDATA函数 (参数1:地址 参数2:写入的数值) 成功返回1 失败返回0
  29. */
  30. bit write_xram(U16 address,U8 value){       
  31.         U8 old_value;
  32.         if(address > max_xram_address) return 0;
  33.         old_value = XBYTE[address];
  34.         if(value == old_value) return 1;
  35.         XBYTE[address]=value;
  36.         value=hash_xram(address,value);
  37.         old_value=hash_xram(address,old_value);
  38.         if(value > old_value){
  39.                 xram_check += (value - old_value);
  40.                 } else {
  41.                 xram_check -= (old_value - value);
  42.         }
  43.         xram_xor^=old_value^value;
  44.         return 1;
  45.        
  46. }
  47. /*
  48. 校验XDATA数据是否正确
  49. 成功返回1,有1字节出错则会返回0,则表示程序已跑飞或被篡改。
  50. 必须使用 write_xram() 函数写入,否则没有改变校验而出错。
  51. */
  52. bit check_xram(){
  53.         U32 xram_check2 = 0;
  54.         U8 xram_xor2 = 0;
  55.         U8 xbyte;
  56.         U16 size = max_xram_address;
  57.         do {
  58.         xbyte=hash_xram(size,XBYTE[size]);
  59.                 xram_xor2^=xbyte;
  60.                 xram_check2+=xbyte;
  61.         } while(size--);
  62.         return xram_check2 == xram_check && xram_xor2 == xram_xor;

  63. }


  64. void Delay250ms()                //@12MHz
  65. {
  66.         unsigned char i, j, k;

  67.         _nop_();
  68.         i = 2;
  69.         j = 231;
  70.         k = 91;
  71.         do
  72.         {
  73.                 do
  74.                 {
  75.                         while (--k);
  76.                 } while (--j);
  77.         } while (--i);
  78. }



  79. void main(){
  80.         U16 size=0;



  81.         while(1){
  82.         size=max_xram_address;
  83.         do {
  84.                 write_xram(size,read_xram(size)+1);
  85.         } while(size--);

  86.                 if(!check_xram()){
  87.                         P3=0x00;
  88.                        
  89.                         while(1){
  90.                         Delay250ms();
  91.                         P3=~P3;
  92.                         }
  93.                         }

  94.                         P3++;
  95.         }
  96. }

复制代码
您需要登录后才可以回帖 登录 | 注册已关闭

本版积分规则

QQ|手机版|Archiver|从F到0 ( 蒙ICP备17002595号-1 )
蒙公网安备15010402000325号

腾讯云安全认证

GMT+8, 2024-4-20 09:31 , Processed in 1.006057 second(s), 16 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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