这段代码可能有什么问题?没有按预期运行

问题描述 投票:0回答:1

在 DOSBox 中使用 TASM 运行汇编代码。我正在尝试在显示器中央打印我的名字。字母应按如下方式打印:第一个字母,然后应显示从第一个字母开始的每个字母以及当前字母,例如 name = carlton

首先打印c
然后 c 和 a
然后 c,a,r
然后 c、a、r、l 等

这是我尝试过的。我得到了一个无限循环,并且没有接近预期的结果。我认为我的方法还可以,但是编码有很多问题。

.MODEL SMALL
    .STACK 64
    .DATA
my_string db "Carlton", 0
count1 db 07
buffer db 07 dup(0)
count2  dw 0ffffh   ;delay
.CODE
MAIN:   mov ax,@DATA
    mov ds,ax
; initialize pointer to point to my_string
   mov bx, offset my_string
   mov di, offset buffer

outer_loop: ; outer loop to iterate through each letter 
;clearing the screen
    MOV AX,0600H    ;scroll the entire page
    MOV BH,07   ;normal attribute
    MOV CX,0000     ;row and column of the top left
    MOV DX,184FH    ;row and column of the bottom right
    INT 10H     ;invoke interrupt 10H
    
    ;setting the cursor to the center of the screen
    MOV AH,02   ;set cursor option
    MOV BH,00   ;page 0
    MOV DL,39   ;center column position
    MOV DH,12   ;center row position
    INT 10H     ;invoke interrupt 10H


        ; print current letter
       
        mov di,[bx] ; store current character in di, wc pionts to buffer
        mov ah,09
        mov dx, di
        int 21h
    dec count2  ;decrement delay
    jnz outer_loop

        ; inner loop to print buffer before current letter
         print_prev:  
       cmp di,[bx]
       je next          
           mov ah, 09
           mov dx, di
           int 21h
           inc di
       jmp print_prev

       ; increment pointer to next letter
        next:
    inc bx
    dec count1
    mov count2,0ffffh
        jnz outer_loop

 ; exit program
    mov ah,4ch
    int 21h
    END MAIN
assembly x86-16 tasm dosbox
1个回答
0
投票

指出里面还有什么乱七八糟的地方?

  • 甚至在尝试打印第一个字母之前,“清除屏幕”和“将光标设置到屏幕中心”就会破坏您的 BX 指针!请记住,BH(用于属性和显示页码)是 BX 寄存器的顶部。

  • 您似乎认为DOS函数09h显示单个字符。事实并非如此:该函数显示以 $ 符号结尾的字符串(并且 $ 符号本身根本不显示)。对于单字符输出,请使用 DOS 功能 02h。

  • 您的outer_loop可能很容易被称为无限循环,因为它会清除屏幕65535次并显示一些垃圾字符。

  • 如果您的 print_prev 循环预计会打印单个字母,那么您对

    inc di
    有何期望,逻辑上会增加一个字符?

  • mov di,[bx] ; store current character in di
    清楚地表明了对指针和方括号的误解。该特定指令从字符串中加载 2 个字符,同时破坏您在 DI 中设置的缓冲区指针。

更具建设性的说明

不清楚你到底想输出到屏幕上的是什么, 但从你的提及来看:

首先打印 c 然后 c 和 a 然后 c,a,r 然后 c,a,r,l 等

我认为您可能正在寻找:

wait 1 sec
1st screen:  c
wait 1 sec
2nd screen:  ca
wait 1 sec
3rd screen:  car
wait 1 sec
4th screen:  carl
wait 1 sec
5th screen:  carlt
wait 1 sec
6th screen:  carlto
wait 1 sec
7th screen:  carlton

下一个代码为例:

  ;clearing the screen

  ;setting the cursor to the center of the screen

  ; showing the name one character at a time
  mov  si, offset my_string
TheLoop:
  ; Wait 1 sec
  mov  ah, 2Ch     ; DOS.GetSystemTime
  int  21h         ; -> CX DX
  mov  bl, dh      ; Keep seconds
NotYet:
  mov  ah, 2Ch     ; DOS.GetSystemTime
  int  21h         ; -> CX DX
  cmp  dh, bl      ; Did seconds change ? 
  je   NotYet
  ; Show next character, previous characters already in place
  mov  dl, [si]
  mov  ah, 02h     ; DOS.DisplayCharacter
  int  21h
  inc  si
  dec  count1
  jnz  TheLoop
© www.soinside.com 2019 - 2024. All rights reserved.