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

vxf3dgd4  于 2023-01-17  发布在  其他
关注(0)|答案(1)|浏览(107)

在DOSOX中使用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
ugmeyewa

ugmeyewa1#

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

  • 甚至在试图打印第一封信之前就会";清除屏幕"和";设置光标到屏幕中心"已经破坏了你的BX指针!记住BH(你用于属性和显示页码)是BX寄存器的顶部。
  • 你似乎认为DOS函数09h只显示一个字符,但事实并非如此:这个函数显示以$符号结尾的字符串($符号本身根本不显示)。2对于单字符输出,使用DOS函数02h。
  • 您的 * outer_loop * 可能很容易被称为无限循环,因为它将清除屏幕65535次,并显示一些垃圾字符。
  • 如果您的 * print_prev * 循环预期打印单个字母,那么您期望从inc di中逻辑上递增一个字符吗?
  • mov di,[bx] ; store current character in di清楚地证明了对指针和方括号的误解。这个特殊的指令从字符串中加载了2个字符的DI,同时破坏了你在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

相关问题