如何缓冲输入作品如何缓冲输入作品(How buffered input works)

2019-05-12 11:10发布

在接下来的程序输入工作确定,但是当我问到显示输出,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 : ', '$'
; --------------------------------------

Answer 1:

看你如何定义你的输入缓冲区( buf: db 20 dup ('$')我明白了,你想抄近路,有输入-封端已经准备好重新显示它$。 可悲的是这打乱了所需的设置为DOS输入功能0AH和你的程序是严重的问题与潜在的缓冲区溢出。
使用另外$ -termination是不是,你可以做,因为$字符可能已经出现跻身输入的字符中最亮的选择。 所有我下面给出的例子程序将使用零终止代替。

使用输入文本int 21h AH=0Ah

这种缓冲STDIN输入功能从键盘获得字符,并继续这样做,直到用户按下Enter键。 所有字符和最终回车被放置在开始于经由在指针由调用程序提供的输入缓冲器的第3字节的存储空间DS:DX
字符计数,不包括最后的回车,被存储在输入缓冲器的第二字节。
这是调用程序告诉DOS存储空间有多大的责任。 因此,你必须把它的输入缓冲区的第一个字节长度调用此函数之前。 为了允许1个字符的输入你2.设置的存储大小,以允许你在255设置的存储大小的254个字符的输入。
如果你不希望能够从模板回忆以往任何输入,那么最好是也为零的第二个字节。 基本上,模板是在调用程序提供的输入缓存器中的预先存在的(合法的)内容。 如果预先存在的内容是无效的,那么该模板不可用。

令人惊讶的这一功能限制了编辑功能。

  • 逃生从当前输入的所有字符。
    电流输入被放弃,但停留在屏幕上光标放在下一行,下方其中,输入第一次开始。
  • Backspace键从当前输入的最后一个字符。
    按预期工作,如果输入的单个行内停留在屏幕上。 如果在另一方面,输入跨越几行,然后该退格将停止在屏幕的左边缘。 从此会有逻辑输入和视觉输入之间严重脱节,因为已达到逻辑上退格将继续,直到存储空间第一的位置!
  • F6插入在当前输入的档案结尾字符(为1Ah)。
    屏幕上会显示“^ Z”。
  • F7插入当前输入一个零字节。
    屏幕上会显示“^ @”。
  • CTRL + ENTER转换到下一行(执行回车和换行),不添加到当前输入,你不能回去。

还有更多的编辑键可用。 他们都是让人想起Edlin.exe将 ,古老的DOS行编辑器,这是每个前行成为其上构建下一行的模板文本编辑器。

  • F1从复制的模板新行一个字符。
  • F2 + ...... +复制模板中的所有字符为新的线路,到指定的字符。
  • F3复制模板中的新行的所有剩余的字符。
  • F4 + ...跳过的人物模板,到指定的字符。
  • F5使新线新模板。
  • 逃生清除当前输入和离开模板不变。
  • 删除模板跳过一个字符。
  • 插入进入或退出插入模式。
  • 退格键删除新行的最后一个字符,并在模板中的光标置于后面一个字符。
  • 同退格键。
  • 与F1。

标签是由该功能扩展。 Tab扩展是由一系列的一个或多个空间(ASCII 32),直到光标到达的列位置是8的倍数的替换ASCII 9的过程。
此选项卡扩展只发生在屏幕上。 存储空间将于9 ASCII。

这个函数CTRL C / 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
; --------------------------------------

使用输入文本int 21h AH=3Fh

当与预定义的手柄0(在使用BX )这个从文件中读取或设备功能从键盘获得字符,并继续这样做,直到用户按回车 。 所有字符(从未超过127个),并最终回车加上额外的换行符放置在DOS内核中的专用缓冲区。 现在,这将成为新的模板。
此后该函数将在所提供的缓冲器写DS:DX ,要求在该字节数CX参数。 如果CX指定一个数字,是小于由该输入产生的字节数,需要一个或多个额外的调用该函数检索完整输入。 只要有剩余的字符被拾起,使用键盘此功能不会启动另一个输入会话! 这是不同的程序或者同一个程序的会话之间,即使真。

在上一节中描述的所有编辑键可用。

标签只,而不是在模板上的屏幕扩大。

这个函数CTRL C / 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,从文件读取或设备,在同一时间拿起一个字节。

        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
; --------------------------------------

使用输入文本int 2Fh AX=4810h

这DOSKEY缓冲STDIN输入功能只能调用如果安装了DOSKEY.COM TSR 。 它操作起来非常象常规缓冲STDIN输入功能0AH(见上文),但所有相同的编辑可能性,在DOS命令行,其中包括使用所有的DOSKEY特殊键的能力。

  • 最多从历史中获取一个项目。
  • 退出历史获取下一个项目。
  • F7显示在历史中的所有项目的列表。
  • ALT + F7清除历史记录。
  • ... F8查找以启动项目(S)...
  • F9按编号选择从历史的项目。
  • Alt键 F10删除所有macrodefinitions。

上DOS 6.2存储空间总是被限制为128个字节,从而允许的127个字符为强制性回车输入和房间。 这是不可能预先加载的模板,所以总是输入缓冲区的第2个字节设置为零。
在DOS Win95的,如果你用以下命令安装DOSKEY.COM TSR的存储空间可以大到255个字节doskey /line:255 。 这是可能的预加载的模板的存储空间。 这使得Win95的版本非常接近的是feasable与输入功能0AH。

这个函数CTRL C / CTRL 检查。

当此功能完成后,光标会在当前行最左边的列。 如果字符计数为零,这意味着用户在DOSKEY宏,尚未扩展的名称输入。 你没有能看到未膨胀的线! 需要此功能的第二次调用,并在返回这个时候,光标会扩展的文本的最后一个字符后面。
一个特点是,当多宏命令( $T )被扩大,你只能得到1号指令的展开文本。 需要的功能的其他调用,以获得其他扩展文本。 虽然这一切是从像COMMAND.COM命令shell中非常有用,从用户应用程序中它真的很烦人,你可以不知道什么时候出现这种情况。

由于输入的文本添加到命令历史记录,这是不可避免的历史与无关的项目填满。 当然不是你想看到在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
; --------------------------------------

使用输入文本int 21h AH=08h

因为堆栈溢出强加文本30000字节限制的继续下面的答案...

问题认识的来源? 我用汇编:

  • considers labels that start with a dot ( . ) as 1st level local labels
  • considers labels that start with a colon ( : ) as 2nd level local labels
  • is Single Instruction Multiple Operands (SIMO), so push cx si translates to push cx push si.


Answer 2:

使用输入文本int 21h AH=08h

描述到现在为止(在上面的答案!)所有三种输入方式显然是量身定做,以适应微软工具,如Edlin.exe将和COMMAND.COM。
如果您正在编写自己的应用程序,然后更好的结果可以通过制作自己的输入程序来实现。 在这样的心脏的过程将是DOS单个字符输入功能中的一个。 我选择了STDIN输入功能08H,因为我想允许CTRL C / CTRL 检查,我打算通过BIOS来呼应人物自己Int 10h AH=09h 写入字符和属性在光标位置 。 这样我就可以避免搞乱了任何重定向输出。

编程有一个在使用这种BufferedInput程序或DOS.BufferedInput系统调用没有区别。 然而,对于在键盘上输入用户因为所有与旧的和困难的模板编辑相关的密钥已被驳回,由通常的编辑键,使您可以自由移动光标周围取而代之的将是更加容易。

  • 向左移动光标离开了。
  • 向右移动光标。
  • 首页将光标移到最左边。
  • 最终将光标移到最右侧。
  • 按Ctrl 首页删除所有字符到左边。
  • 按Ctrl 最终删除所有字符的权利。
  • 删除删除当前字符。
  • 退格键删除字符光标的左侧。
  • 逃亡删除所有的字符。
  • 返回结束输入。

如果输入缓冲器的第二字节保存一个非零值,则所述存储空间被认为(从先前输入也许)包含旧字符串。 DOS会叫这个模板。 从DOS不同的是:

  • 旧的字符串不要求回车结束。
  • 旧的字符串会立即显示在屏幕上。

在输入过程中,标签扩大,输入被限制在当前行内停留。 较长的文本会水平滚动。
当输入终于完成了,完成的文本选项卡扩展编写一次(在屏幕上,存储空间将始终保持ASCII 9),并不再限制为单行。

这个过程确实CTRL C / CTRL 检查。

当这个过程完成时,光标会在当前行最左边的列。

这个过程与写输入重定向和输出重定向记,因而非常适合控制台应用程序。
输入重定向的一个作用是,它是无用的呼应任何临时输出到屏幕上。 任一用户是不存在在屏幕凝视或临时输出将在眨眼消​​失。

实施例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
; --------------------------------------

问题认识的来源? 我用汇编:

  • 认为以点开始的标签(。)为第一级局部标签
  • 认为以冒号开始的标签(:)为2级局部标签
  • 是单指令多操作数(SIMO),所以push cx si转化为push cx push si

对于一个真正高性能的输入过程,看看丰富的编辑表单输入 ,代码审查的贡献。



文章来源: How buffered input works