【问题标题】:Don't know how to print an entire Calendar at once [closed]不知道如何一次打印整个日历 [关闭]
【发布时间】:2015-04-05 02:02:47
【问题描述】:
cseg segment
assume cs:cseg, ds:cseg
org 100H
begin:   
                mov es,cs:[video]
                mov ax,3
                int 10h 
                mov cs:[col],0fh
                mov di,10               ;greeting msg will be printed after 10 spaces
                lea si,greeting
                call mess
                call nline        
                call jan
                call nline
                mov ah,4ch
                int 21h

col             db 0
greeting        db "Welcome to the 2015 Calendar ",0  
video           dw 0b800h
january         db  "         January$",     
string          db  "Sun Mon Tue Wed Thu Fri Sat$"
string1         db  "         1   2   3   4   5$"
string2         db  " 6   7   8   9  10  11  12$"
string3         db  "13  14  15  16  17  18  19$"
string4         db  "20  21  22  23  24  25  26$"
string5         db  "27  28  29  30  31$"

mess            proc
                push ax
                mov ah,cs:[col]
                mov bh, 30
conmess:
                mov al,cs:[si]
                or al,al
                jz endmess
                mov es:[di],ax  
                mov es:[di+1],bh
                inc si
                add di,2
                jmp conmess
endmess:
                pop ax
                ret
mess            endp

nline           proc
                mov ah, 2                    ; carriage return
                mov DL, 0DH
                int 21H    
                mov DL, 0AH                  ; line feed
                int 21H 
                ret
nline           endp   

print: 
                ;printing the line
                mov bh,10h  ;color attribute
                mov ah,9 
                mov al,0  ;avoding extra characters
                int 10h   ;printing color
                int 21h
                ret 

jan             proc 
                lea dx,january               ; load & display the STRIN
                call print
                call nline
                lea dx, string               ; load & display the STRING 
                call print
                call nline
                lea dx, string1              ; load & display the STRING 
                call print
                call nline
                lea DX, string2               ; load & display the STRING 
                call print
                call nline
                lea DX, string3               ; load & display the STRING 
                call print 
                call nline
                lea DX, string4               ; load & display the STRING 
                call print      
                call nline
                lea DX, string5               ; load & display the STRING 
                call print
                call nline 
                ret
jan             endp

cseg ends
end begin

【问题讨论】:

    标签: assembly dos


    【解决方案1】:
    assume cs:cseg, ds:cseg
    org 100H
    

    因为您使用了org 100h,所以我假设您正在编写 DOS'.COM 格式的可执行文件。

    mov di,10               ;greeting msg will be printed after 10 spaces
    

    要产生 10 个空格,您需要设置 DI=20,因为在 0B800h 的视频 RAM 中,每个字符占用 2 个字节。

    mess  proc
      push ax
      mov ah,cs:[col]
      mov bh, 30         ; You don't need this line
     conmess:
      mov al,cs:[si]
      or al,al
      jz endmess
      mov es:[di],ax  
      mov es:[di+1],bh   ; You don't need this line
      inc si
      add di,2
      jmp conmess
     endmess:
      pop ax
      ret
    mess  endp
    

    欢迎信息通过直接写入视频 RAM 来显示。为什么要插入2种方式来定义属性字节?

    print:
     mov bh,10h  ; Delete this line
     mov ah,9 
     mov al,0    ; Delete this line
     int 10h     ; Delete this line
     int 21h
     ret
    

    其余的写作是通过 DOS 函数完成的。这个 print 例程似乎混合了 BIOS 和 DOS 功能!!!对于 DOS,您只需要 AH=9

    mov ah,4ch
    int 21h
    

    Terminate 函数要求您在 AL 寄存器中定义退出代码。使用mov ax,4C00h

    您无需繁琐地调用 nline 来生成 CRLF,您可以轻松地将这两个字节写入您要输出的字符串中。
    像这个例子

    string2         db  " 6   7   8   9  10  11  12",13,10,"$"
    

    您的大多数例程都是使用 PROC/ENDP 声明的,但 print 不是。请选择一个系统并坚持下去。

    编辑

    由于您的所有字符串都显示在单独的行上,因此为它们提供颜色的最简单解决方案是使用所需的属性擦除当前行。这是第一个字符串的操作方法

    mov ax,0920h                    \
    mov bx,001Eh  ;Yellow on Blue    | Best put this in a subroutine!
    mov cx,80                        |
    int 10h                         /
    lea dx,january
    call print
    call nline
    

    【讨论】:

    • 非常感谢。但是,还有一件事我需要用彩色打印。我遇到了麻烦。有没有办法以颜色突出显示的格式编写所有这些字符串?
    • 我在输出中添加了颜色。
    • 谢谢你这个代码完全有效
    • 总是很高兴看到它有效!你能被说服接受答案吗?您知道您也因此而获得声誉吗?
    • @0ptimus :这是一个古老的问题和答案。既然答案解决了你的问题,你能接受答案吗?谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-12-17
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    相关资源
    最近更新 更多