당신이 당신의 입력 버퍼 (buf: db 20 dup ('$')
)를 정의하는 방법을 보면서, 나는 그것을 얻을 당신이 모서리를 잘라 원하는 이미 그것을 다시 표시 준비 $로 끝나는 입력이 . 안타깝게도 이것은 DOS 입력 기능 0Ah에 필요한 설정을 엉망으로 만들고 프로그램은 잠재적 인 버퍼 오버런에 심각한 문제가 있습니다.
또한 $ 문자를 이미 입력 된 문자 사이에 표시 할 수 있으므로 $ -termination을 사용하면 을 만들 수있는 가장 밝은 선택이 아닙니다. 아래 제시된 모든 예제 프로그램은 제로 - 종료 을 대신 사용합니다.
int 21h AH=0Ah
이 Buffered STDIN Input 기능을 사용하여 입력하기 텍스트는 키보드에서 문자를 얻고 사용자가 가 Enter 키를 누를 때까지 는 그렇게 계속합니다. 문자와 최종 캐리지 리턴은 이 호출 프로그램 에 의해 제공된 입력 버퍼의 세 번째 바이트부터 시작하여 DS:DX
에있는 포인터를 통해 저장 공간에 저장됩니다.
마지막 캐리지 리턴을 제외한 문자 수는 입력 버퍼의 두 번째 바이트 에 저장됩니다.
저장 공간의 크기를 DOS에 알려주는 것은 호출 프로그램의 책임입니다. 따라서이 함수를 호출하기 전에 길이를 입력 버퍼의 첫 번째 바이트에 넣어야합니다. 1 문자의 입력을 허용하려면 저장 크기를 2로 설정하십시오. 254 문자의 입력을 허용하려면 255로 저장 크기를 설정하십시오.
에서 템플릿 이전 입력, 다음 두 번째 바이트를 0으로하는 것이 가장 좋습니다. 기본적으로 템플리트는 호출 프로그램 이 제공 한 입력 버퍼에있는 기존의 (유효한) 내용 입니다. 기존 콘텐츠가 유효하지 않은 경우 템플릿에 을 사용할 수 없습니다.
놀랍게도이 기능에는 편집 기능이 제한되어 있습니다.
- Escape 현재 입력에서 모든 문자를 제거합니다.
현재 입력이 취소되었지만 화면에 그대로 유지되고 커서가 에 입력이 처음 시작된 위치의 다음 행에 배치됩니다.
- 백 스페이스 현재 입력에서 마지막 문자를 제거합니다.
입력이 화면의 단일 행 내에 있으면 예상대로 작동합니다. 반면에 입력이 여러 행에 걸쳐있는 경우이 백 스페이스는 화면의 왼쪽 가장자리에서 멈 춥니 다. 그 이후부터 논리적으로 저장 공간의 첫 번째 위치에 도달 할 때까지 계속 진행되므로 논리 입력과 시각 입력 사이에 심각한 차이가 나타납니다 ( ).
- F6 현재 입력에 파일 끝 문자 (1Ah)를 삽입합니다.
화면에 "^ Z"가 표시됩니다.
- F7 현재 입력에 0 바이트를 삽입합니다.
화면에 "^ @"이 표시됩니다.
- Ctrl 키를는 다음 행의 (a 캐리지 리턴과 라인 피드를 실행), 아무것도 현재의 입력에 추가되지 않습니다에 전환을 입력하면 돌아갈 수 없습니다.
더 많은 편집 키를 사용할 수 있습니다. 그들은 모두 을 연상케합니다. EDLIN.EXE, 이전의 각 줄 이 다음 줄을 만드는 데 사용되는 서식 파일이되는 텍스트 편집기 인 고대 DOS 줄 편집기.
- F1 복사 새로운 라인 템플릿에서 하나 개의 문자.
- F2 + ... 지정된 문자까지 템플릿의 모든 문자를 새 줄에 복사합니다.
- F3 템플릿의 나머지 문자를 모두 새 줄에 복사합니다.
- F4 + ... 템플릿의 문자를 통해 스킵, 최대 지정된 문자.
- F5 새 줄을 새 서식 파일로 만듭니다.
- Escape 현재 입력 내용을 지우고 템플리트를 변경하지 않습니다.
- 삭제 템플릿의 한 문자를 건너 뜁니다.
- 삽입 삽입 모드를 시작하거나 종료합니다.
- 백 스페이스 새 줄의 마지막 문자를 삭제하고 커서를 템플릿의 한 문자 뒤로 가져옵니다.
- 왼쪽 백 스페이스와 동일합니다.
- 오른쪽 F1과 동일합니다.
탭은이 기능으로 확장됩니다. 탭 확장은 커서가 에 8의 배수 인 열 위치에 도달 할 때까지 ASCII 9를 일련의 하나 이상의 공백 (ASCII 32)으로 바꾸는 프로세스입니다.
이 탭 확장은 화면에서만 발생합니다. 저장 공간에는 ASCII 9가 저장됩니다.
이 함수가 CTRLC/CTRL브레이크 검사.
이 함수가 끝나면 커서는 현재 행의 맨 왼쪽 열에 있습니다.
예제 1, 버퍼링 된 STDIN 입력.
ORG 256 ;Create .COM program
cld
mov si, msg1
call WriteStringDOS
mov dx, buf
mov ah, 0Ah ;DOS.BufferedInput
int 21h
mov si, msg2
call WriteStringDOS
mov si, buf+2
movzx bx, [si-1] ;Get character count
mov word [si+bx+1], 10 ;Keep CR, append LF and 0
call WriteStringDOS
mov ax, 4C00h ;DOS.TerminateWithExitcode
int 21h
; --------------------------------------
; IN (ds:si) OUT()
WriteStringDOS:
pusha
jmps .b
.a: mov dl, al
mov ah, 02h ;DOS.DisplayCharacter
int 21h ; -> AL
.b: lodsb
test al, al
jnz .a
popa
ret
; --------------------------------------
buf: db 255, 16, "I'm the template", 13, 255-16-1+2 dup (0)
msg1: db 'Choose color ? ', 0
msg2: db 10, 'You chose ', 0
; --------------------------------------
(BX
에) 미리 정의 된 핸들 0와 함께 사용하면이 Read From File Or Device 기능은 키보드에서 문자를 가져오고 사용자가를 입력 누를 때까지 그렇게 계속 int 21h AH=3Fh
를 사용하여 입력하기 텍스트입니다. 모든 문자 (결코 127 개 이상)와 최종 캐리지 리턴과 추가 줄 바꿈은 DOS 커널 내의 전용 버퍼에 저장됩니다. 이것은 이제 새로운 템플릿이됩니다.
이후이 함수는 DS:DX
에 제공된 버퍼에 매개 변수에 요청 된 바이트 수인 을 씁니다. CX
이이 입력에 의해 생성 된 바이트 수보다 작은 숫자 으로 지정된 경우, 전체 입력을 검색하려면이 함수에 대한 하나 이상의 추가 호출이 필요합니다. 픽업 할 문자가 남아있는 한이 기능은 키보드를 사용하여 다른 입력 세션을 시작하지 않습니다! 동일한 프로그램의 서로 다른 프로그램 또는 세션 사이에서도 마찬가지입니다.
이전 섹션에서 설명한 모든 편집 키를 사용할 수 있습니다.
탭은 템플릿이 아닌 화면에서만 확장됩니다.
이 함수가 CTRLC/CTRL브레이크 검사. 종단 바꿈 반환 된 바이트 중 아니라면
이 기능 완료
는 커서
- 현재 행의 맨 왼쪽 컬럼에있을 것이다.
- 끝나는 줄 바꿈이 반환 된 바이트 중 하나 인 경우 다음 행.
예 2a, 파일 또는 장치에서 읽기, 한 번에 모두 선택하십시오.
ORG 256 ;Create .COM program
cld
mov si, msg1
call WriteStringDOS
mov dx, buf
mov cx, 127+2 ;Max input is 127 chars + CR + LF
xor bx, bx ;STDIN=0
mov ah, 3Fh ;DOS.ReadFileOrDevice
int 21h ; -> AX CF
jc Exit
mov bx, ax ;Bytes count is less than CX
mov si, msg2
call WriteStringDOS
mov si, buf
mov [si+bx], bh ;Keep CR and LF, append 0 (BH=0)
call WriteStringDOS
Exit: mov ax, 4C00h ;DOS.TerminateWithExitcode
int 21h
; --------------------------------------
; IN (ds:si) OUT()
WriteStringDOS:
pusha
jmps .b
.a: mov dl, al
mov ah, 02h ;DOS.DisplayCharacter
int 21h ; -> AL
.b: lodsb
test al, al
jnz .a
popa
ret
; --------------------------------------
buf: db 127+2+1 dup (0)
msg1: db 'Choose color ? ', 0
msg2: db 'You chose ', 0
; --------------------------------------
예제 2b, 파일 또는 장치에서 읽기, 한 번에 한 바이트 씩 가져옵니다.int 2Fh AX=4810h
이 DOSKEY Buffered STDIN Input 기능을 사용하여 텍스트를 입력하기
ORG 256 ;Create .COM program
cld
mov si, msg1
call WriteStringDOS
mov dx, buf
mov cx, 1
xor bx, bx ;STDIN=0
mov ah, 3Fh ;DOS.ReadFileOrDevice
int 21h ; -> AX CF
jc Exit
mov si, msg2
call WriteStringDOS
mov si, dx ;DX=buf, CX=1, BX=0
Next: mov ah, 3Fh ;DOS.ReadFileOrDevice
int 21h ; -> AX CF
jc Exit
call WriteStringDOS ;Display a single byte
cmp byte [si], 10
jne Next
Exit: mov ax, 4C00h ;DOS.TerminateWithExitcode
int 21h
; --------------------------------------
; IN (ds:si) OUT()
WriteStringDOS:
pusha
jmps .b
.a: mov dl, al
mov ah, 02h ;DOS.DisplayCharacter
int 21h ; -> AL
.b: lodsb
test al, al
jnz .a
popa
ret
; --------------------------------------
msg1: db 'Choose color ? ', 0
msg2: db 10, 'You chose '
buf: db 0, 0
; --------------------------------------
는 if the DOSKEY.COM TSR was installed를 호출 할 수 있습니다. 그것은 정상적인 Buffered STDIN 입력 기능 0Ah (위 참조)와 매우 비슷하게 작동하지만 DOSKEY 특수 키를 모두 사용할 수있는 기능을 포함하여 DOS 명령 줄과 동일한 편집 가능성을 모두 가지고 있습니다.
- 위로 기록에서 이전 항목을 가져옵니다.
- 아래로 기록에서 다음 항목을 가져옵니다.
- F7 기록에있는 모든 항목의 목록을 표시합니다.
- altF7 기록을 지 웁니다.
...
F8은 - F9가 숫자로 기록에서 항목을 선택 ... 시작 아이템 (들)을 찾아 낸다.
- altF10 모든 매크로 정의를 제거합니다.
DOS 6.2에서는 저장 공간이 항상 128 바이트로 제한되어 있으므로 은 127 자이며 필수 캐리지 리턴 공간이 허용됩니다. 템플릿을 미리로드 할 수 없기 때문에 항상 입력의 두 번째 바이트를 0으로 설정하십시오.
doskey /line:255
과 같은 명령으로 DOSKEY.COM TSR을 설치 한 경우 DOS Win95에서 저장 공간은 255 바이트가 될 수 있습니다. 템플릿을 사용하여 저장 공간을 미리로드 할 수 있습니다. 이것은 Win95 버전 을 입력 기능 0Ah로 실행 가능한 것과 매우 가깝게 만듭니다.
이 함수가 CTRLC/CTRL브레이크 검사.
이 함수가 끝나면 커서는 현재 행의 맨 왼쪽 열에 있습니다. 문자 수가 0이면 사용자가 에 아직 확장되지 않은 DOSKEY 매크로의 이름을 입력했음을 의미합니다. 당신은 확장되지 않은 라인을 볼 수 없어! 함수의 두 번째 호출은 이어야하며이 시간을 반환하면 커서는 확장 된 문자 의 마지막 문자 뒤에 있습니다.
다중 명령 매크로 ($T
)가 확장되면 첫 번째 명령의 확장 된 텍스트 만 가져 오는 것이 특징입니다. 다른 확장 텍스트를 얻으려면 함수를 추가로 호출해야합니다. 이 모든 것은 이지만 COMMAND와 같은 명령 셸 내에서 매우 유용합니다.COM, 사용자 내에서 응용 프로그램이 발생하면 정말 언제 당신이 알 수 없다고 짜증나.
입력 된 텍스트가 명령 기록에 추가되었으므로 관련없는 항목으로 채워지는 것이 불가피합니다. DOS 프롬프트에서 을보고 싶지 않을 것입니다.
예제 3, DOSKEY.COM 호출.
ORG 256 ;Create .COM program
cld
mov ax, 4800h ;DOSKEY.CheckInstalled
int 2Fh ; -> AL
test al, al
mov si, err1
jz Exit_
Again: mov si, msg1
call WriteStringDOS
mov dx, buf
mov ax, 4810h ;DOSKEY.BufferedInput
int 2Fh ; -> AX
test ax, ax
mov si, err2
jnz Exit_
cmp [buf+1], al ;AL=0
je Again ;Macro expansion needed
mov si, msg2
call WriteStringDOS
mov si, buf+2
movzx bx, [si-1] ;Get character count (is GT 0)
mov word [si+bx+1], 10 ;Keep CR, append LF and 0
Exit_: call WriteStringDOS
Exit: mov ax, 4C00h ;DOS.TerminateWithExitcode
int 21h
; --------------------------------------
; IN (ds:si) OUT()
WriteStringDOS:
pusha
jmps .b
.a: mov dl, al
mov ah, 02h ;DOS.DisplayCharacter
int 21h ; -> AL
.b: lodsb
test al, al
jnz .a
popa
ret
; --------------------------------------
buf: db 128, 0, 128+2 dup (0)
msg1: db 'Choose color ? ', 0
msg2: db 13, 10, 'You chose ', 0
err1: db 'N/A', 13, 10, 0
err2: db 'Failed', 13, 10, 0
; --------------------------------------
사용하여 입력하기 텍스트로 인해 스택 오버플로가 아래의 답변을 계속 텍스트를 부과 30000 바이트 제한의 int 21h AH=08h
... 소스를 이해
문제? 내가 사용하는 어셈블러 (. )
- 는 점 콜론 (:)로 시작
- 레이블을 고려 1 단계 지역 레이블로 시작 레이블 고려 2 단계 지역 라벨 등을
- 은 SIMO (Single Instruction Multiple Operans)이므로
push cx si
은 push cx
push si
으로 변환됩니다.