String 使用DOS中断MASM获取字符串输入和显示输入
在MASM中,我创建了一个缓冲区变量来保存来自键盘的用户字符串输入。我一直在研究如何将字符串输入保存到缓冲区变量中。我没有任何像irvine那样链接的库,我想用DOS中断来实现这一点。到目前为止,我有一些类似于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) ;
.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