Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 使用DOS中断MASM获取字符串输入和显示输入_String_Assembly_Input_Keyboard_Masm - Fatal编程技术网

String 使用DOS中断MASM获取字符串输入和显示输入

String 使用DOS中断MASM获取字符串输入和显示输入,string,assembly,input,keyboard,masm,String,Assembly,Input,Keyboard,Masm,在MASM中,我创建了一个缓冲区变量来保存来自键盘的用户字符串输入。我一直在研究如何将字符串输入保存到缓冲区变量中。我没有任何像irvine那样链接的库,我想用DOS中断来实现这一点。到目前为止,我有一些类似于 .model small .stack 100h .data buff db 25 dup(0), 10, 13 lbuff EQU ($ - buff) ;

在MASM中,我创建了一个缓冲区变量来保存来自键盘的用户字符串输入。我一直在研究如何将字符串输入保存到缓冲区变量中。我没有任何像irvine那样链接的库,我想用DOS中断来实现这一点。到目前为止,我有一些类似于

            .model small

            .stack 100h

            .data
buff        db  25 dup(0), 10, 13
lbuff       EQU ($ - buff)              ; bytes in a string

            .code
main:
            mov ax, @data
            mov ds, ax              

            mov ah, 0Ah         ; doesn't work
            mov buff, ah        ; doesn't seem right
            int 21h                 


            mov     ax, 4000h       ; display to screen
            mov     bx, 1           
            mov     cx, lbuff           
            mov     dx, OFFSET buff     
            int     21h 

            mov ah, 4ch
            int 21h

            end main

我假设使用0Ah是正确的,因为它用于读取缓冲字符的输入数组。

我对您的代码做了一些更改。首先,“buff”变量需要三级格式(允许的最大字符数、输入字符数的另一个字节以及缓冲区本身),因为这是服务0AH所需要的。为了使用服务0AH,我添加了“补偿增益”(正如沃尔夫冈所说)。这是:

            .model small

            .stack 100h

            .data

buff        db  26        ;MAX NUMBER OF CHARACTERS ALLOWED (25).
            db  ?         ;NUMBER OF CHARACTERS ENTERED BY USER.
            db  26 dup(0) ;CHARACTERS ENTERED BY USER.

            .code
main:
            mov ax, @data
            mov ds, ax              

;CAPTURE STRING FROM KEYBOARD.                                    
            mov ah, 0Ah ;SERVICE TO CAPTURE STRING FROM KEYBOARD.
            mov dx, offset buff
            int 21h                 

;CHANGE CHR(13) BY '$'.
            mov si, offset buff + 1 ;NUMBER OF CHARACTERS ENTERED.
            mov cl, [ si ] ;MOVE LENGTH TO CL.
            mov ch, 0      ;CLEAR CH TO USE CX. 
            inc cx ;TO REACH CHR(13).
            add si, cx ;NOW SI POINTS TO CHR(13).
            mov al, '$'
            mov [ si ], al ;REPLACE CHR(13) BY '$'.            

;DISPLAY STRING.                   
            mov ah, 9 ;SERVICE TO DISPLAY STRING.
            mov dx, offset buff + 2 ;MUST END WITH '$'.
            int 21h

            mov ah, 4ch
            int 21h

            end main
当0AH从键盘捕获字符串时,它以ENTER(字符13)结尾,这就是为什么,如果要捕获25个字符,必须指定26

要知道用户输入的字符数(长度),请访问第二个字节(偏移量buff+1)。ENTER不包括在内,因此,如果用户键入8个字符并输入ENTER,则第二个字节将包含数字8,而不是9


输入的字符从偏移量buff+2开始,在出现字符13时结束。我们使用它将长度添加到buff+2+1,用“$”替换chr(13)。现在我们可以显示字符串了。

这是我的代码,也许可以帮助您

;Input String Copy output

dataarea segment
    BUFFER db 81
           db ?
    STRING DB 81 DUP(?)
    STR1 DB 10,13,'$'   
dataarea ends

extra segment
    MESS1 DB 'After Copy',10,13,'$'
    MESS2 DB 81 DUP(?)
extra ends

code segment
main proc far
    assume cs:code,ds:dataarea,es:extra
start:
    push ds
    sub ax,ax
    push ax

    mov ax,dataarea   
    mov ds,ax

    mov ax,extra      
    mov es,ax

    lea dx,BUFFER     
    mov ah,0ah
    int 21h

    lea si,STRING
    lea di,MESS2
    mov ch,0
    mov cl,BUFFER+1
    cld
    rep movsb
    mov al,'$'
    mov es:[di],al

    lea dx,STR1            ;to next line
    mov ah,09h
    int 21h

    push es
    pop ds

    lea dx,MESS1           ;output:after copy
    mov ah,09h
    int 21h

    lea dx,MESS2
    mov ah,09h
    int 21h

    ret
main endp
code ends
    end start
结果是:

c:\demo.exe
Hello World!
After Copy
Hello World!

您可以遵循以下代码:

; Problem : input array from user

.MODEL SMALL
.STACK
.DATA
   ARR DB 10 DUB (?)     

.CODE
 MAIN PROC
    MOV AX, @DATA
    MOV DS, AX

    XOR BX, BX
    MOV CX, 5

    FOR: 
      MOV AH, 1
      INT 21H
      MOV ARR[BX], AL
      INC BX
    LOOP FOR

    XOR BX, BX
    MOV CX, 5

    PRINT:  
     MOV AX, ARR[BX] ;point to the  current index 

     MOV AH, 2       ;output
     MOV DL, AX  
     INT 21H     

     INC BX           ;move pointer to the next element 
    LOOP PRINT       ;loop until done

 MAIN ENDP

);试试这个,它接受用户输入的10个字符的字符串,然后以这种方式显示“Hello*10character string input”


int 21h/0Ah
需要
dx
中的缓冲区地址。缓冲区中的第一个字节需要是max input。通过将
ah
填入其中,您已经说过您需要10个字符(可能需要更多)。中断返回后,第二个字节是输入的实际字符数。输入文本从缓冲区+2开始。@FrankKotler Ok,所以我通过执行mov dx,偏移量25 mov ah,0Ah int 21h部分实现了它的工作(抱歉,我不确定如何在注释中格式化)。那么输入的字符从dx+2开始?如何将其移动到buff变量中?dx寄存器中的输入函数需要缓冲区的开始“mov dx,OFFSET buff”和缓冲区第一个字节中的最大输入,例如,10个字符的“mov[buff],ah”。输出函数需要“mov-dx,OFFSET-buff+2”和输入的实际字符数“mov-cl,[buff+1]”@DirkWolfgangGlomp,因此它应该是
mov-dx,OFFSET-buff+2,而不是
。然后
mov-cx,lbuff
需要变成
mov-cl[buff+1]
,因为这将在字符串移位+2后为您提供正确的字符串长度,对吗?那么我在哪里做
mov[buff],啊
?就在mov ah,0Ah之前?是:这三行代码都在buff变量中。是:如果您想修改字符串中的字符,您必须将SI点设置为buff+2。使用40h或4000h(我不知道为什么是4000h,它是我的参考资料的一部分)而不是使用09h函数会更容易吗?这样就不必在字符串的末尾有一个“$”?我能告诉你的缺点是,即使用户没有输入完整的25个字符,它也会显示所有的25个字符。如果你知道长度,你可以用ah=13h加int 10h(就像这个答案),但是,如果你不想为长度操心,你可以用$。我从来没有试过40小时或4000小时。@JoseManuelAbarcaRodriguez你不必从22步走到29步,把美元放在CH(13)上。您只需将
db 26 dup(0)
替换为该
db 26 dup(“$”)
.MODEL TINY
.CODE
.286
ORG 100h

    START:
     MOV DX, OFFSET BUFFER
     MOV AH, 0ah
     INT 21h
     JMP PRINT
     BUFFER DB 10,?, 10 dup(' ')

     PRINT:
     MOV AH, 02
     MOV DL, 0ah
     INT 21h
     MOV AH, 9
     MOV DX, OFFSET M1
     INT 21h
     XOR BX, BX
     MOV BL, BUFFER[1]
     MOV BUFFER [BX+2], '$'
     MOV DX, OFFSET BUFFER +2
     MOV AH, 9
     INT 21h

    M1: db 'Hello $'


 END START
 END