菜農自賀5年後數組彙編82字節雷翻了dengm同志90字節的萬年曆彙編

/*-----------------------------------------------------------------------

函數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)

長度: 82字節

-----------------------------------------------------------------------*/

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)

};

真正的萬年曆: 90 bytes 的 51 ASM

;==SUB_WNL=== 萬年曆 ==* Deng Miao * 2004-05-27 ***** GuangZhou ******

SJ DATA 30H ; 世紀 BCD 00 TO 99

NH DATA 31H ; 年號 BCD 00 TO 99 0000 TO 9999 年

YF DATA 32H ; 月份 BCD 01 TO 12

org 000h

MOV SP, #40H

MOV SJ, #20H ;2004-05

MOV NH, #04H

MOV YF, #05H

ACALL SUB_WNL

SJMP $

;===============SUB_WNL===================

; 入口:

; SJ DATA 30H ; 世紀 BCD 00 TO 99

; NH DATA 31H ; 年號 BCD 00 TO 99 0000 TO 9999 年

; YF DATA 32H ; 月份 BCD 01 TO 12

; 出口

; ACC -- 本月天數 BCD 28 to 31

; B -- 本月1日的星期數 1 to 6 == 星期1 to 星期6

; 0 -- 星期日

; 使用 ACC, B, R5,R6

; STACK: 3 bytes (不包括調用)

ORG 50H

; SJ/4 400年大週期

; DateDiff("d", #1/1/2000#, #1/1/2400#)

; =146097天 = 7 * 20871 + 0 天

; 100年 = 7 * 5217 + 6

; 200年 = 7 * 10435 + 4

; 300年 = 7 * 15653 + 2

;

SUB_WNL:

PUSH PSW

MOV A, SJ

ACALL BCD2BIN_DIV4

CPL A

INC A

ANL A, #03H

RL A

MOV R5, A ; R5: 星期 0/6/4/2

MOV A, NH

JZ WNL_1

ACALL BCD2BIN_DIV4

WNL_1:

MOV A, YF

ADD A, #(WNL_TAB-$-4)

MOVC A, @A+PC

MOV R6, A

SWAP A

ACALL WNL_F0

ADDC A, R5

;ADD A, #6; 0000-01-01 星期 6

MOV B, #7

DIV AB

MOV A, R6

ACALL WNL_F0

ADDC A, #28

POP PSW

RET

WNL_TAB:

DB 3*2 + 6 * 32+0 ;1

DB 0*2+1 + 2 * 32+0 ;2

DB 3*2 + 2 * 32+16 ;3

DB 2*2 + 5 * 32+16 ;4

DB 3*2 + 0 * 32+16 ;5

DB 2*2 + 3 * 32+16 ;6

DB 3*2 + 5 * 32+16 ;7

DB 3*2 + 1 * 32+16 ;8

DB 2*2 + 3 * 32+16 ;9

WNL_F0: ; 6 BYTES ;

RRC A ;0AH

ANL A, #07H ;0BH

;0CH

ANL C, F0 ;0DH

;0EH

RET ;0FH

DB 3*2 + 5 * 32+16 ;10H

DB 2*2 + 1 * 32+16 ;11H

DB 3*2 + 3 * 32+16 ;12H

BCD2BIN_DIV4:

MOV R6, A

ANL A, #0F0H

SWAP A

MOV B, #(256-6)

MUL AB

ADD A, R6

MOV B, #4

DIV AB

MOV R6, B

;-------------------------------------

MOV B, #5 ; 3 * 365 + 366 = 7*208 + 5

MUL AB

ADD A, R6 ; 366 = 7*52 + 2

; 366 + 365 = 7*104 + 3

; 366 + 365 + 365 = 7*156+4

MOV C, F0

ADDC A, R5

MOV R5, A

MOV A, R6

JNZ WNL_EXT

DEC R5

SETB C

WNL_EXT:

MOV F0, C

RET

;-----------------------------

END ;======== END OF FILE


分享到:


相關文章: