老刘001 发表于 2017-6-11 10:20:22

Show_Str、DivDW、DtoC函数块

本帖最后由 老刘001 于 2017-6-11 12:26 编辑

终于学完了Call&Ret
自己动手写了3个王爽&甲鱼老师要求的函数块……
DEBUG 2小时……

DivDW.ASM
DivDW:        ;至少需要6Byte栈空间
        ;参数:
        ;(DX)=DW型被除数高16位
        ;(AX)=DW型被除数低16位
        ;(CX)=W型除数

        ;返回:
        ;(DX)=DW型商的高16位
        ;(AX)=DW型商的低16位
        ;(CX)=余数

        ;一阶段:int(H/N)的计算
        PUSH        BX        ;BX可用
        PUSH        AX
        MOV        AX,DX
        SUB        DX,DX        ;(DX)=0
        DIV        CX        ;(AX)=商 (DX)=余数
        MOV        BX,AX
        POP        AX        ;(AX)=DW型被除数低16位
        PUSH        BX        ;备份int(H/N)
        ;此时 (AX)=DW型被除数低16位 (DX)=余数=rem(H/N)

        ;二阶段:(rem(H/N)*FFFFH+L)/N的计算以及收尾工作
        DIV        CX        ;(DX)=余数 (AX)=商
        MOV        CX,DX        ;(CX)=(DX)=余数
        POP        DX
        POP        BX        ;还原BX
        RET

DtoC.ASM 这个是双字版的,当时看到后面还要重写双字版就决定直接写双字版了{:10_256:}
DtoC:        ;必须和DivDW函数块一起使用,栈空间至少20Byte。
        ;功能:将Dword型数转变为十进制数的字符串,以0结尾。

        ;参数:
        ;(AX)=DW型数据的低16位
        ;(DX)=DW型数据的高16位
        ;DS:SI指向字符串的首地址。

        ;返回:DS:SI原位置被字符串覆盖,以0结尾,AX,DX被清零。

        PUSH        SI
        PUSH        CX        ;备份CX
        PUSH        BX        ;备份BX
        PUSH        DI        ;备份DI
        PUSH        SI        ;再次备份初始地址SI
        XOR        DI,DI
        XOR        BX,BX

        DtoC_Loop1:
        MOV        CX,0AH
        CALL        DivDW
        ADD        CL,30H
        MOV        ,CL
        MOV        CX,AX
        JCXZ        DtoC_Judge
        INC        SI
        INC        BX
        JMP        DtoC_Loop1

        DtoC_Judge:
        MOV        CX,DX
        JCXZ        DtoC_Next
        INC        SI
        INC        BX
        JMP        DtoC_Loop1

        DtoC_Next:
        POP        SI
        PUSH        SI

        PUSH        BX
        MOV        CX,BX
        MOV        DI,BX
        INC        CX

        DtoC_Loop2:        ;备份并翻转
        MOV        BX,CX
        SUB        BX,1
        MOV        AL,
        MOV        BX,DI
        MOV        ,AL
        INC        DI
        LOOP DtoC_Loop2

        POP        BX
        POP        SI
        MOV        CX,BX
        INC        CX
        DtoC_Loop3:        ;还原
        MOV        AL,
        MOV        ,AL
        INC        SI
        LOOP DtoC_Loop3

        ;收尾
        MOV        BYTE PTR ,0
        POP        DI
        POP        BX
        POP        CX
        SUB        AX,AX
        XOR        DX,DX
        POP        SI
        RET


show_str.ASM
            ;栈空间至少10Byte
   SHOW_STR:;功能:显示DS开头的字符串,以0结尾。

            ;参数:
            ;(DH)=屏幕缓存区的行号(范围1-25)
            ;(DL)=列号(范围1-80)
            ;(CL)=颜色

            PUSH      AX          ;备份
            PUSH      BX
            PUSH      SI
            PUSH      SI
            XOR       SI,SI
            MOV       AX,0B800H   ;屏幕缓冲区
            MOV       ES,AX
            XOR       AX,AX
            XOR       BX,BX
            ;AX、BX、SI空闲&可用
            SUB       DH,1
            MOV       AL,DH
            MOV       BL,0A0H
            MUL       BL          ;计算行的偏移
            XOR       DH,DH
            ;DH可用
            SUB       DL,1                           
            ADD       DX,DX       ;计算列的偏移
            ADD       AX,DX       ;得到整体偏移量
            ADD       SI,AX       ;SI赋值为整体偏移量
            XOR       AX,AX       ;AX空闲&可用
            XOR       DX,DX       ;DX空闲&可用
                           
            POP       BX          ;BX定位内存中的字符
            MOV       DL,CL       ;DL储存字符颜色
            SUB       CX,CX       ;CX用来储存字符Ascii码并判断跳出
            
          SHOW_STR_LOOP:
            MOV       CL,
            JCXZ      SHOW_STR_FINISH
            MOV       ES:,CL
            MOV       ES:,DL
            ADD       SI,2
            INC       BX
            JMP       SHOW_STR_LOOP

      SHOW_STR_FINISH:
            POP       SI
            POP       BX
            POP       AX
            RET
页: [1]
查看完整版本: Show_Str、DivDW、DtoC函数块