首页 > 解决方案 > 循环输入组件 x86

问题描述

该程序需要遍历用户输入的输入并将找到的每个下划线字符(“_”)替换为“@”。
该程序会执行此操作,但只需一次,然后找到的每个下划线字符都保持不变。

.MODEL SMALL
.STACK
.DATA
    string_input DB "Enter a string: $"
    string_output DB "Your string is: $" 
 
 
    bufferLong db 250  
    inputLong db 0
    buffer db 250, 0, 250 dup ("$"), "$"
 
.CODE 
 
start:
    mov ax, @data
    mov ds, ax
 
    mov dx, offset string_input
    mov ah, 09h
    int 21h
 
    call inputString
 
   ;mov cl, al 
 
    mov dl, 0Ah
    mov ah, 02h
    int 21h
 
    mov dl, 0Dh
    mov ah, 02h
    int 21h
 
    mov dx, offset string_output
    mov ah, 09h
    int 21h
 
    ;mov al, cl
 
 
    call outputString
 
    mov ax, 4C00h
    int 21h
 
 
 
    inputString proc 
        mov dx, offset bufferLong
        mov ah, 0Ah
 
        int 21h 
        ret
        inputString endp
 
    outputString proc
        mov dx, offset buffer
        mov ah, 09h
        mov si,0
        mov cx, 0
        mov bl, "_"
 
        loop:
            cmp bl, buffer[si]
            je replace
            inc cx
            inc si
            jne loop 
 
        replace: 
            mov buffer[si], "@"
 
        int 21h
        ret
        outputString endp
 
    end start

标签: loopsassemblyx86-16

解决方案


bufferLong db 250  
inputLong db 0
buffer db 250, 0, 250 dup ("$"), "$"

这看起来你并不真正知道这个 DOS.BufferedInput 函数 0Ah 所需的输入结构应该是什么样子。在缓冲输入的工作原理中了解更多信息。
这是正确的定义:

bufferLong db 250  
inputLong db 0
buffer db 250 dup (0)

在第一次替换时,您立即打印结果,实际上您应该继续循环。最好像这样将条件跳转更改为相反的(从jejne):

        xor si, si
    loop:
        mov al, buffer[si]
        cmp al, 13
        je  print           ; Exit the loop upon finding 13
        cmp al, "_"
        jne skip            ; While skipping you stay in the loop
    replace: 
        mov buffer[si], "@"
    skip:
        inc si
        jmp loop            ; Unconditionally to the top where a possible exit can get detected

    print:
        mov buffer[si], "$"
        mov dx, offset buffer
        mov ah, 09h
        int 21h
        ret

您的“循环”缺少的是一种清晰的退出方式。您处理的字符串以回车符 (13) 结尾。使用它来停止迭代。如果用户没有输入字符而只是使用了 ,这可能从一开始就发生enter
接下来,您需要提供正确的字符串终止符,以便 DOS 可以打印结果。用$字符预加载输入缓冲区没有任何意义。只需存储一个$字符,或者替换字节 13,或者在字节 13 后面。


推荐阅读