2017-11-19 1 views
4

다음 프로그램의 입력은 정상적으로 작동하지만 출력을 표시 할 때 DOS 에 아무 것도 표시되지 않습니다! 이것이 어떻게 가능한지?버퍼링 된 입력 작동 방법

 ORG  256 
     mov  dx, msg1 
     mov  ah, 09h     ;DOS.WriteString 
     int  21h 
     mov  dx, buf 
     mov  ah, 0Ah     ;DOS.BufferedInput 
     int  21h 
     mov  dx, msg2 
     mov  ah, 09h     ;DOS.WriteString 
     int  21h 
     mov  dx, buf 
     mov  ah, 09h     ;DOS.WriteString 
     int  21h 
     mov  ax, 4C00h    ;DOS.TerminateWithExitcode 
     int  21h 
; -------------------------------------- 
msg1: db  'Input : ', '$' 
buf: db  20 dup ('$') 
msg2: db  13, 10, 'Output : ', '$' 
; -------------------------------------- 

답변

3

당신이 당신의 입력 버퍼 (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 sipush cxpush si으로 변환됩니다.
2

지금까지 (위의 답!에) 설명 int 21h AH=08h

세 가지 입력 방법을 사용하여 입력하기 텍스트는 명확 맞춤형 인 Edlin.exe 및 COMMAND.COM 같은 Microsoft 도구를 맞게되었다.
자신의 응용 프로그램을 작성하는 경우 자신의 입력 절차를 통해 더 나은 결과를 얻을 수 있습니다. 이러한 절차의 핵심은 은 DOS 단일 문자 입력 기능 중 하나입니다. 내가 Ctrl 키를C/Ctrl 키를휴식을 검사를 할 수 있도록 원하기 때문에 나는 STDIN Input 기능 08H를 선택하고 난 BIOS Int 10h AH=09h Write Character And Attribute At Cursor Position를 통해 문자 나 자신 에코하려는 . 이 방법은 내가 리디렉션 된 출력을 엉망으로 만들 수 있습니다.

는 프로그래밍이 BufferedInput 절차 또는 DOS.BufferedInput 시스템 호출을 사용에는 차이가 없습니다. 그러나 키보드 사용자의 경우 이전 입력 키와 관련된 모든 키와 템플릿 편집이 어려운 템플릿 편집이 해제되어 커서를 자유롭게 이동할 수있는 일반적인 편집 키로 바뀌었기 때문에 훨씬 쉽게 입력 할 수 있습니다.

  • 왼쪽 커서를 왼쪽으로 이동합니다.
  • 오른쪽 커서를 오른쪽으로 이동합니다.
  • 커서를 맨 왼쪽으로 이동합니다.
  • 커서를 맨 오른쪽으로 이동합니다.
  • Ctrl 왼쪽의 모든 문자를 제거합니다.
  • Ctrl 오른쪽의 모든 문자를 제거합니다.
  • 삭제 현재 문자를 제거합니다.
  • 백 스페이스 커서 왼쪽에있는 문자를 제거합니다.
  • Escape 모든 문자를 제거합니다.
  • 돌아 가기 입력을 끝내십시오.

입력 버퍼의 두 번째 바이트가 0이 아닌 값을 보유하면 저장 공간 에 이전 입력의 어쩌면 이전 문자열이 포함되어 있다고 가정합니다. 도스는 이 템플릿을 호출했을 것입니다. 도스와 다른 점은 다음과 같습니다.

  • 이전 문자열은 캐리지 리턴 종료가 필요하지 않습니다.
  • 이전 문자열이 화면에 즉시 표시됩니다.

입력이 진행되는 동안는 탭 확장하지을하며 입력 현재 행 내에 머물고에 국한된다. 더 긴 텍스트는 수평으로 스크롤됩니다.
입력이 완료되면 완료된 텍스트는 탭 확장 (화면에는 저장 공간이 항상 ASCII 9를 유지)으로 기록되고 더 이상 단일 행으로 제한되지 않습니다.

이 절차를 수행 Ctrl 키를C/Ctrl 키를브레이크 검사.

이 절차가 완료되면 커서가 현재 행의 맨 왼쪽 열에있게됩니다.

이 절차는 input redirection and output redirection를 염두에두고 작성되었으므로 콘솔 응용 프로그램에 적합합니다.
입력 리다이렉션의 한 가지 효과는 임시 출력을 화면에 에코하는 것이 효과적이지 않다는 것입니다. 사용자가 화면을 바라 보지 않거나 일시적인 출력이 눈 깜짝 할 사이에 사라집니다.

예제 4, 향상된 버퍼 STDIN 입력.

 ORG  256      ;Create .COM program 
     cld 
     mov  si, msg1 
     call WriteStringDOS 
     mov  dx, buf 
     call BufferedInput   ;Replaces 'mov ah, 0Ah : 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 
; -------------------------------------- 
; IN (ds:dx) OUT() 
BufferedInput: 

; Entry DS:DX Buffer of max 1+1+255 bytes 
;    1st byte is size of storage space starting at 3rd byte 
;    2nd byte is size of old (CR-terminated) string, 0 if none 
;    Storage space can contain old (CR-terminated) string 
; Exit DS:DX Nothing changed if header bytes were invalid 
;    1st byte unchanged 
;    2nd byte is size of new CR-terminated string 
;    Storage space contains new CR-terminated string 
; Local [bp-1] PAGE Display page 
;  [bp-2] STORE Size of storage space 
;  [bp-3] ROW  Row of input box 
;  [bp-4] COL  Column of input box 
;  [bp-5] SHIFT Number of characters shifted out on the leftside 
;  [bp-6] INBOX Size of input box 
;  [bp-7] LIX  Number of characters in current input string 
;  [bp-8] CIX  Position of cursor in current input string 
;  [bp-10] FLAGS Bit[0] is ON for normal keyboard input 

     pusha 
     mov  si, dx 
     lodsw       ; -> SI points at storage space 
     test al, al     ;AL is size of storage space 
     jz  .Quit     ;No storage space! 
     cmp  ah, al     ;AH is size of old string 
     jnb  .Quit     ;Old string too long! 
     mov  bl, al 

     sub  sp, 256     ;Local edit buffer (max size) 
     mov  bp, sp 
     mov  ah, 0Fh     ;BIOS.GetVideoMode 
     int  10h      ; -> AL=Mode AH=Cols BH=Page 
     push bx      ;STORE and PAGE 
     mov  bl, ah 
     mov  ah, 03h     ;BIOS.GetCursor 
     int  10h      ; -> CX=Shape DL=Col DH=Row 
     push dx      ;COL and ROW 
     sub  bl, dl     ;Size of the widest inbox 
     xor  bh, bh 
     push bx      ;INBOX and SHIFT 
     push bx      ;CIX and LIX (replaces 'sub sp, 2') 

     call .ESC     ;Clear edit buffer, reset some vars 
     mov  cl, [si-1]    ;Size of old string (starts at SI) 
     jmps .b 
.a:  lodsb       ;Storage space gives old string 
     push cx si 
     call .Asc     ;Input old string 
     pop  si cx 
.b:  sub  cl, 1 
     jnb  .a 

     xor  bx, bx     ;STDIN 
     mov  ax, 4400h    ;DOS.GetDeviceInformation 
     int  21h      ; -> AX DX CF 
     jc  .c      ;Go default to keyboard 
     test dl, dl 
     jns  .d      ;Block device, not keyboard 
     shr  dl, 1 
.c:  adc  bx, bx     ; -> BX=1 if Keyboard 
.d:  push bx      ;FLAGS 

.Main: call .Show     ;Refresh input box on screen 
     call .Key     ;Get key from DOS -> AX 
     mov  bx, .Scans 
     test ah, ah 
     jz  .f      ;Not an extended ASCII 
     mov  [cs:.Fail], ah   ;Sentinel 
.e:  lea  bx, [bx+3] 
     cmp  ah, [cs:bx-1] 
     jne  .e 
.f:  call [cs:bx] 
     jmps .Main 

.Quit: popa       ;Silently quiting just like DOS 
     ret 
; - - - - - - - - - - - - - - - - - - - 
.Scans: db   .Asc 
     db  4Bh, .s4B    ;<LEFT> 
     db  4Dh, .s4D    ;<RIGHT> 
     db  47h, .s47    ;<HOME> 
     db  4Fh, .s4F    ;<END> 
     db  77h, .s77    ;<CTRL-HOME> 
     db  75h, .s75    ;<CTRL-END> 
     db  53h, .s53    ;<DELETE> 
.Fail: db  ?, .Beep 
; - - - - - - - - - - - - - - - - - - - 
.Beep: mov  ax, 0E07h    ;BIOS.TeletypeBell 
     int  10h 
     ret 
; - - - - - - - - - - - - - - - - - - - 
.Key: call :1 
     test ah, ah     ;Extended ASCII requires 2 calls 
     jnz  :2 
:1:  mov  ah, 08h     ;DOS.STDINInput 
     int  21h      ; -> AL 
     mov  ah, 0 
:2:  xchg al, ah 
     ret 
; - - - - - - - - - - - - - - - - - - - 
.Show: test word [bp-10], 1   ;FLAGS.Keyboard ? 
     jz  :Ready     ;No, input is redirected 
     movzx di, [bp-6]    ;INBOX 
     movzx si, [bp-5]    ;SHIFT 
     mov  dx, [bp-4]    ;COL and ROW 
     mov  cx, 1     ;Replication count 
     mov  bh, [bp-1]    ;PAGE 
     mov  bl, 07h     ;WhiteOnBlack 
:Next: mov  ah, 02h     ;BIOS.SetCursor 
     int  10h 
     mov  al, [bp+si] 
     mov  ah, 09h     ;BIOS.WriteCharacterAndAttribute 
     int  10h 
     inc  dl      ;Next column 
     inc  si      ;Next character 
     dec  di 
     jnz  :Next     ;Process all of the input box 

     mov  dx, [bp-4]    ;COL and ROW 
     add  dl, [bp-8]    ;CIX 
     sub  dl, [bp-5]    ;SHIFT 
     mov  ah, 02h     ;BIOS.SetCursor 
     int  10h 
:Ready: ret 
; - - - - - - - - - - - - - - - - - - - 
.BS: cmp  byte [bp-8], 0   ;CIX 
     jne  :1 
     ret 
:1:  call .s4B     ;<LEFT> 
; --- --- --- --- --- --- -- 
; <DELETE> 
.s53: movzx di, [bp-8]    ;CIX 
     movzx cx, [bp-7]    ;LIX 
     sub  cx, di 
     je  :2      ;Cursor behind the current input 
:1:  mov  dl, [bp+di+1]   ;Move down in edit buffer 
     mov  [bp+di], dl 
     inc  di 
     dec  cx 
     jnz  :1 
     dec  byte [bp-7]    ;LIX 
:2:  ret 
; - - - - - - - - - - - - - - - - - - - 
.RET: xor  si, si 
     mov  bx, [bp+256+10]   ;pusha.DX -> DS:BX 
     mov  al, [bp-7]    ;LIX 
     inc  bx 
     mov  [bx], al    ;2nd byte is size of new string 
     inc  bx 
     jmps :2 
:1:  mov  dl, [bp+si] 
     mov  [bx+si], dl    ;Storage space receives new string 
     inc  si 
:2:  sub  al, 1 
     jnb  :1 
     mov  byte [bx+si], 13  ;Terminating CR 

     push bx      ;(1) 
     call .ESC     ;Wipe clean the input box 
     call .Show     ; and reset cursor 
     pop  si      ;(1) -> DS:SI 
:3:  lodsb       ;Final unrestricted display, 
     mov  dl, al     ; expanding tabs 
     mov  ah, 02h     ;DOS.DisplayCharacter 
     int  21h      ; -> AL 
     cmp  dl, 13     ;Cursor ends in far left column 
     jne  :3 

     lea  sp, [bp+256]   ;Free locals and edit buffer 
     popa 
     ret 
; - - - - - - - - - - - - - - - - - - - 
.ESC: mov  di, 256     ;Fill edit buffer with spaces 
:1:  sub  di, 2 
     mov  word [bp+di], " " 
     jnz  :1 
     mov  [bp-8], di    ;DI=0 -> CIX=0 LIX=0 
     mov  byte [bp-5], 0   ;SHIFT=0 
     ret 
; - - - - - - - - - - - - - - - - - - - 
.Asc: cmp  al, 8     ;<BACKSPACE> 
     je  .BS 
     cmp  al, 13     ;<RETURN> 
     je  .RET 
     cmp  al, 27     ;<ESCAPE> 
     je  .ESC 
     cmp  al, 10     ;Silently ignoring linefeed 
     jne  :1      ; in favor of input redirection 
     ret 
:1:  movzx di, [bp-8]    ;CIX 
     movzx si, [bp-7]    ;LIX 
     lea  dx, [si+1] 
     cmp  dl, [bp-2]    ;STORE 
     jb  :3 
     jmp  .Beep     ;Storage capacity reached 
:2:  mov  dl, [bp+si-1]   ;Move up in edit buffer 
     mov  [bp+si], dl 
     dec  si 
:3:  cmp  si, di 
     ja  :2 
     mov  [bp+si], al    ;Add newest character 
     inc  byte [bp-7]    ;LIX 
; --- --- --- --- --- --- -- 
; <RIGHT> 
.s4D: inc  byte [bp-8]    ;CIX 
     mov  al, [bp-7]    ;LIX 
     cmp  [bp-8], al    ;CIX 
     jbe  .Shift 
     mov  [bp-8], al    ;CIX 
     ret 
; - - - - - - - - - - - - - - - - - - - 
; <LEFT> 
.s4B: sub  byte [bp-8], 1   ;CIX 
     jnb  .Shift 
; --- --- --- --- --- --- -- 
; <HOME> 
.s47: mov  byte [bp-8], 0   ;CIX 
     jmps .Shift 
; - - - - - - - - - - - - - - - - - - - 
; <END> 
.s4F: mov  al, [bp-7]    ;LIX 
     mov  [bp-8], al    ;CIX 
; --- --- --- --- --- --- -- 
.Shift: mov  dl, [bp-5]    ;SHIFT 
     mov  al, [bp-8]    ;CIX 
     cmp  al, dl 
     jb  :1 
     add  dl, [bp-6]    ;INBOX 
     sub  al, dl 
     jb  :2 
     inc  al 
     add  al, [bp-5]    ;SHIFT 
:1:  mov  [bp-5], al    ;SHIFT 
:2:  ret 
; - - - - - - - - - - - - - - - - - - - 
; <CTRL-HOME> 
.s77: call .BS 
     cmp  byte [bp-8], 0   ;CIX 
     ja  .s77 
     ret 
; - - - - - - - - - - - - - - - - - - - 
; <CTRL-END> 
.s75: call .s53     ;<DELETE> 
     mov  al, [bp-8]    ;CIX 
     cmp  al, [bp-7]    ;LIX 
     jb  .s75 
     ret 
; -------------------------------------- 
buf: db  255, 16, "I'm an OldString", 13, 255-16-1+2 dup (0) 
msg1: db  'Choose color ? ', 0 
msg2: db  10, 'You chose ', 0 
; -------------------------------------- 

소스를 이해하는 데 문제가 있습니까?내가 사용하는 어셈블러 (. )

  • 는 점 콜론 (:)로 시작
  • 레이블을 고려 1 단계 지역 레이블로 시작 레이블 고려 2 단계 지역 라벨 등을
  • 은 SIMO (Single Instruction Multiple Operans)이므로 push cx sipush cxpush si으로 변환됩니다. 정말 고성능의 입력 절차는

, Rich Edit Form Input하는 코드 검토 기여 봐.

관련 문제