/*---------------------------------------------------------------------------- HotC51宏汇编数组定义头文件(hotmacro.h V1.09) 最初建立时间: 2009.2.18 最近修改时间: 2009.3.10 增 添原 因: 为全面支持裸奔式实时操作系统HotTask51做准备 hotmacro.h宣告“宏C”计划开始, 支持Keil C51带参数输入输出的"汇编数组之过程与函数"。 HotC51使用宏汇编数组可以方便地与Keil C51“通讯” 应 用: 可以用COM接口技术对HotC51汇编数组进行封装 macro_Function_Arg3 (CRCR8, macro_U8_arg1, macro_U8_arg2, macro_U8_arg3) { #define CRCR8_LOOP -15 #define CRCR8_NEXT size_XRL_A_Rn() asm_MOV_B(8),//设置8位计数器 //CRCR8_LOOP: asm_MOV_A_Rn(macro_U8_arg3),//取明文 asm_XRL_A_Rn(macro_U8_arg1),//异或初值 asm_RRC_A(),//右移CRC8一位,注意ACC.0移入CY asm_MOV_A_Rn(macro_U8_arg1),//再取初值 asm_JNC(CRCR8_NEXT),//CY为0不异或权,跳过下句 asm_XRL_A_Rn(macro_U8_arg2),//异或权 //CRC8R_NEXT: asm_RRC_A(),//将CY移入ACC.7 asm_MOV_Rn_A(macro_U8_arg1),//保存本次结果 asm_MOV_A_Rn(macro_U8_arg3),//再取明文 asm_RR_A(),//准备下一位 asm_MOV_Rn_A(macro_U8_arg3),//保存明文,注意已改变 asm_DJNZ_B(CRCR8_LOOP),//未完继续到CRCR8_LOOP macro_return(), }; 未 来计 划: 首先将HotC51汇编数组做成比宏汇编更好用的接近C习惯. 逐步完善,最终全面到达“宏C”之目标。 菜农HotPower@126.com 2008.3.10 18:58 于西安大雁塔村农会 -----------------------------------------------------------------------------*/
#include "hotwc3.h" /*----------------------------------------------------------------------- 函数CRCR8(macro_U8_arg1, macro_U8_arg2, macro_U8_arg3) 入口: macro_U8_arg1 初值 macro_U8_arg2 权 macro_U8_arg3 明文 出口: macro_U8_Result CRCR8结果 -----------------------------------------------------------------------*/ macro_Function_Arg3 (CRCR8, macro_U8_arg1, macro_U8_arg2, macro_U8_arg3) { #define CRCR8_LOOP -15 #define CRCR8_NEXT size_XRL_A_Rn() asm_MOV_B(8),//设置8位计数器 //CRCR8_LOOP: asm_MOV_A_Rn(macro_U8_arg3),//取明文 asm_XRL_A_Rn(macro_U8_arg1),//异或初值 asm_RRC_A(),//右移CRC8一位,注意ACC.0移入CY asm_MOV_A_Rn(macro_U8_arg1),//再取初值 asm_JNC(CRCR8_NEXT),//CY为0不异或权,跳过下句 asm_XRL_A_Rn(macro_U8_arg2),//异或权 //CRC8R_NEXT: asm_RRC_A(),//将CY移入ACC.7 asm_MOV_Rn_A(macro_U8_arg1),//保存本次结果 asm_MOV_A_Rn(macro_U8_arg3),//再取明文 asm_RR_A(),//准备下一位 asm_MOV_Rn_A(macro_U8_arg3),//保存明文,注意已改变 asm_DJNZ_B(CRCR8_LOOP),//未完继续到CRCR8_LOOP /*--------------------------------------------- //将初值安排在Arg1可节省下面2句 asm_MOV_A_Rn(macro_U8_arg1),//取结果 asm_MOV_Rn_A(macro_U8_Result),//送返回值 ----------------------------------------------*/ macro_return(), };
/*----------------------------------------------------------------------- 函数CRCL8(macro_U8_arg1, macro_U8_arg2, macro_U8_arg3) 入口: macro_U8_arg1 初值 macro_U8_arg2 权 macro_U8_arg3 明文 出口: macro_U8_Result CRCR8结果 -----------------------------------------------------------------------*/ macro_Function_Arg3 (CRCL8, macro_U8_arg1, macro_U8_arg2, macro_U8_arg3) { #define CRCL8_LOOP -15 #define CRCL8_NEXT size_XRL_A_Rn() asm_MOV_B(8),//设置8位计数器 //CRCL8_LOOP: asm_MOV_A_Rn(macro_U8_arg3),//取明文 asm_XRL_A_Rn(macro_U8_arg1),//异或初值 asm_RLC_A(),//左移CRC8一位,注意ACC.7移入CY asm_MOV_A_Rn(macro_U8_arg1),//再取初值 asm_JNC(CRCL8_NEXT),//CY为0不异或权,跳过下句 asm_XRL_A_Rn(macro_U8_arg2),//异或权 //CRC8R_NEXT: asm_RLC_A(),//将CY移入ACC.0 asm_MOV_Rn_A(macro_U8_arg1),//保存本次结果 asm_MOV_A_Rn(macro_U8_arg3),//再取明文 asm_RL_A(),//准备下一位 asm_MOV_Rn_A(macro_U8_arg3),//保存明文,注意已改变 asm_DJNZ_B(CRCL8_LOOP),//未完继续到CRCL8_LOOP /*--------------------------------------------- //将初值安排在Arg1可节省下面2句 asm_MOV_A_Rn(macro_U8_arg1),//取结果 asm_MOV_Rn_A(macro_U8_Result),//送返回值 ----------------------------------------------*/ macro_return(), };
/*----------------------------------------------------------------------- 函数Week(macro_U16_arg1, macro_U8_arg2, macro_U8_arg3) 入口: macro_U16_arg1 年(0x00~0x9999)BCD码 macro_U8_arg2 月(0x01~0x12)BCD码 macro_U8_arg3 日(0x01~0x31)BCD码 出口: macro_U8_Result 星期(0~6) -----------------------------------------------------------------------*/ macro_Function_Arg3 (Week, macro_U16_arg1, macro_U8_arg2, macro_U8_arg3) { #define Week_LOOP -20 asm_MOV_R1(4),//将百年、年、月、日的BCD码换成二进制数 //Week_LOOP: asm_MOV_A(0x4f),//DataBuffer偏移,程序长度 //分别取出macro_U16H_arg1,macro_U16L_arg1macro_U8_arg2, macro_U8_arg3 asm_MOVC_A_aDPTR(), asm_MOV_R0_A(), asm_MOV_A_iR0(), asm_ANL_A(0x0f), asm_XCH_A_iR0(), asm_SWAP_A(), asm_ANL_A(0x0f), asm_MOV_B(10), asm_MUL_AB(), asm_ADD_A_iR0(), asm_MOV_iR0_A(), asm_INC_DPTR(), asm_DJNZ_R1(Week_LOOP),//四次未完继续 //(星期=百年%4*5+年+年/4+(13*月+8)/5+日)%7,特别注意1月2月的年为"去年" asm_CJNE_Rn(macro_U8_arg2, 0x03, 0),//判断月 asm_JNC(size_MOV_A_Rn() + size_ORL_A() + size_MOV_Rn_A() + size_DEC_Rn() + size_CJNE_Rn() + size_DEC_Rn()),//月 //月<=2 asm_MOV_A_Rn(macro_U8_arg2), asm_ORL_A(0x04),//1月2月同5月六月表 asm_MOV_Rn_A(macro_U8_arg2), asm_DEC_Rn(macro_U16L_arg1),//1月2月的年为"去年" asm_CJNE_Rn(macro_U16L_arg1, 0xff, size_DEC_Rn()),//Week_Start asm_DEC_Rn(macro_U16H_arg1), //Week_Start: //百年%4*5 asm_MOV_A_Rn(macro_U16H_arg1),//百年 asm_ANL_A(0x03), asm_MOV_Rn_A(macro_U16H_arg1),//百年%4 asm_CLR_C(), asm_RLC_A(), asm_CLR_C(), asm_RLC_A(),//百年%4*4 asm_ORL_A_Rn(macro_U16H_arg1),//百年%4*5 asm_MOV_Rn_A(macro_U16H_arg1),//保存(百年%4*5),最大值3*5=15 //年+年/4 asm_MOV_A_Rn(macro_U16L_arg1),//年 asm_CLR_C(), asm_RRC_A(), asm_CLR_C(), asm_RRC_A(), asm_ADD_A_Rn(macro_U16L_arg1),//年+年/4 asm_MOV_Rn_A(macro_U16L_arg1),//保存(年+年/4),最大值99+25=124 asm_MOV_A_Rn(macro_U8_arg2),//月 asm_MOV_B(13), asm_MUL_AB(),//13*月->A asm_MOV_B(8), asm_ADD_A_B(),//13*月+8 asm_MOV_B(5), asm_DIV_AB(),//(13*月+8)/5 商->A asm_MOV_Rn_A(macro_U8_arg2),//保存((13*月+8)/5)最大值33 //日 asm_ADD_A_Rn(macro_U8_arg3),//日,最大值31 asm_ADDC_A_Rn(macro_U16H_arg1),//(百年%4*5),最大值15 asm_ADDC_A_Rn(macro_U16L_arg1),//(年+年/4),最大值99+25=124 /* 此时ACC最大为15+124+33+31=203, 注意,蔡勒公式内无203.-2*C可能会越界,菜农给出的蔡勒公式完整表述: W = (203+C/4-2*C+Y+Y/4+(13*M+8)/5+D)%7 菜农星期公式: W = ( C%4*5+Y+Y/4+(13*M+8)/5+D)%7 */ asm_MOV_B(7),//取余数%7 asm_DIV_AB(), asm_XCH_A_B(), asm_MOV_Rn_A(macro_U8_Result),//送返回值(星期) macro_return(), //数据区DataBuffer asm_DB(macro_U16H_arg1), asm_DB(macro_U16L_arg1), asm_DB(macro_U8_arg2), asm_DB(macro_U8_arg3) };
code const IHotWc3Com_Interface wc3Function =//物理分配的COM接口 { (unsigned char (*)(unsigned char arg1, unsigned char arg2, unsigned char arg3))CRCR8, (unsigned char (*)(unsigned char arg1, unsigned char arg2, unsigned char arg3))CRCL8, (unsigned char (*)(unsigned int arg1, unsigned char arg2, unsigned char arg3))Week, };
/*-------------------------------------------- 定义COM接口 --------------------------------------------*/ //com函数指针表 interface { unsigned char (*CRCR8)(unsigned char arg1, unsigned char arg2, unsigned char arg3); unsigned char (*CRCL8)(unsigned char arg1, unsigned char arg2, unsigned char arg3); unsigned char (*Week)(unsigned int arg1, unsigned char arg2, unsigned char arg3); }IHotWc3Com_Vtbl_Interface, *pIHotWc3Com_Vtbl_Interface;
//com函数调用的com接口 interface { const IHotWc3Com_Vtbl_Interface Vtbl;//com函数指针表 }IHotWc3Com_Interface, *pIHotWc3Com_Interface;
void main() { unsigned char crcr8, crcl8; unsigned char week; //HotC51汇编数组宏全面支持带参数输入输出的"数组函数" crcr8 = wc3Function.Vtbl.CRCR8(0, 0x18, 0xff);//初值,权, 明文 crcl8 = wc3Function.Vtbl.CRCL8(0, 0x18, 0x01);//初值,权, 明文 week = wc3Function.Vtbl.Week(0x2009, 0x03, 0x10);//2009年3月10日的BCD码 //................................ }
|