How buffered input works

前端 未结 2 1129
深忆病人
深忆病人 2020-11-27 08:05

The input in next program works OK, but when I ask to display the output, DOS doesn\'t display anything at all! How is this possible?

        ORG     256
           


        
相关标签:
2条回答
  • 2020-11-27 08:38

    Looking at how you defined your input buffer (buf: db 20 dup ('$')), I get it that you want to cut corners and have the input already $-terminated ready for re-displaying it. Sadly this messes up the required settings for the DOS input function 0Ah and your program is in serious problems with a potential buffer overrun.
    Moreover using $-termination is not the brightest choice that you can make since the $ character could already appear amongst the inputted characters. All the example programs that I present below will use zero-termination instead.

    Inputting text using int 21h AH=0Ah

    This Buffered STDIN Input function gets characters from the keyboard and continues doing so until the user presses the Enter key. All characters and the final carriage return are placed in the storage space that starts at the 3rd byte of the input buffer supplied by the calling program via the pointer in DS:DX.
    The character count, not including the final carriage return, is stored in the 2nd byte of the input buffer.
    It's the responsibility of the calling program to tell DOS how large the storage space is. Therefore you must put its length in the 1st byte of the input buffer before calling this function. To allow for an input of 1 character you set the storage size at 2. To allow for an input of 254 characters you set the storage size at 255.
    If you don't want to be able to recall from the template any previous input, then it is best to also zero the 2nd byte. Basically the template is the pre-existing (and valid) content in the input buffer that the calling program provided. If pre-existing content is invalid then the template is not available.

    Surprisingly this function has limited editing facilities.

    • Escape Removes all characters from the current input.
      The current input is abandoned but stays on screen and the cursor is placed on the next row, beneath where the input first started.
    • Backspace Removes the last character from the current input.
      Works as expected if the input stays within a single row on screen. If on the other hand the input spans several rows then this backspacing will stop at the left edge of the screen. From then on there will be a serious discrepancy between the logical input and the visual input because logically backspacing will go on until the 1st position in the storage space is reached!
    • F6 Inserts an end-of-file character (1Ah) in the current input.
      The screen will show "^Z".
    • F7 Inserts a zero byte in the current input.
      The screen will show "^@".
    • ctrlEnter Transitions to the next row (executing a carriage return and linefeed), nothing is added to the current input, and you can't go back.

    Many more editing keys are available. They are all reminiscent of EDLIN.EXE, the ancient DOS line editor, which is a text editor where each previous line becomes the template on which you build the next line.

    • F1 Copies one character from the template to the new line.
    • F2 + ... Copies all characters from the template to the new line, up to the character specified.
    • F3 Copies all remaining characters in the template to the new line.
    • F4 + ... Skips over the characters in the template, up to the character specified.
    • F5 Makes the new line the new template.
    • Escape Clears the current input and leaves the template unchanged.
    • Delete Skips one character in the template.
    • Insert Enters or exits insert mode.
    • Backspace Deletes the last character of the new line and places the cursor back one character in the template.
    • Left Same as Backspace.
    • Right Same as F1.

    Tabs are expanded by this function. Tab expansion is the process of replacing ASCII 9 by a series of one or more spaces (ASCII 32) until the cursor reaches a column position that is a multiple of 8.
    This tab expansion only happens on screen. The storage space will hold ASCII 9.

    This function does ctrlC/ctrlBreak checking.

    When this function finishes, the cursor will be in the far left column on the current row.

    Example 1, Buffered STDIN input.

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

    Inputting text using int 21h AH=3Fh

    When used with predefined handle 0 (in BX) this Read From File Or Device function gets characters from the keyboard and continues doing so until the user presses Enter. All characters (never more than 127) and the final carriage return plus an additional linefeed are placed in a private buffer within the DOS kernel. This now becomes the new template.
    Hereafter the function will write in the buffer provided at DS:DX, the amount of bytes that were requested in the CX parameter. If CX specified a number that is less than the number of bytes generated by this input, one or more additional calls to this function are required to retrieve the complete input. As long as there are characters remaining to be picked up, this function will not launch another input session using the keyboard! This is even true between different programs or sessions of the same program.

    All the editing keys described in the previous section are available.

    Tabs are expanded on screen only, not in the template.

    This function does ctrlC/ctrlBreak checking.

    When this function finishes, the cursor will be in the far left column on the

    • current row if the terminating linefeed was not among the returned bytes.
    • next row if the terminating linefeed was among the returned bytes.

    Example 2a, Read From File Or Device, pick up all at once.

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

    Example 2b, Read From File Or Device, pick up one byte at a time.

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

    Inputting text using int 2Fh AX=4810h

    This DOSKEY Buffered STDIN Input function can only be invoked if the DOSKEY.COM TSR was installed. It operates much like the regular Buffered STDIN Input function 0Ah (see above), but has all the same editing possibilities as the DOS command line, including the ability to use all of the DOSKEY special keys.

    • Up Gets previous item from history.
    • Down Gets next item from history.
    • F7 Shows a list of all the items in the history.
    • AltF7 Clears the history.
    • ...F8 Finds item(s) that start with ...
    • F9 Selects an item from the history by number.
    • AltF10 Removes all macrodefinitions.

    On DOS 6.2 the storage space is always limited to 128 bytes, allowing an input of 127 characters and room for the mandatory carriage return. It's not possible to pre-load a template, so always set the 2nd byte of the input buffer to zero.
    On DOS Win95 the storage space can be as big as 255 bytes if you installed the DOSKEY.COM TSR with a command like doskey /line:255. It's possible to pre-load the storage space with a template. This brings the Win95 version very close to what is feasable with input function 0Ah.

    This function does ctrlC/ctrlBreak checking.

    When this function finishes, the cursor will be in the far left column on the current row. If the character count is zero, it means that the user typed in the name of a DOSKEY macro that was not yet expanded. You don't get to see the un-expanded line! A second invocation of the function is needed and upon returning this time, the cursor will be behind the last character of the expanded text.
    A peculiarity is that when a multi-command macro ($T) gets expanded, you only get the expanded text of the 1st command. Additional invocations of the function are needed to get the other expanded texts. Although all of this is very useful from within a command shell like COMMAND.COM, from within a user application it's really annoying that you can't know when this happens.

    Since the inputted text is added to the command history, it is unavoidable that the history fills up with unrelated items. Certainly not what you want to see at the DOS prompt!

    Example 3, Invoking 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
    ; --------------------------------------
    

    Inputting text using int 21h AH=08h

    Because of the 30000 byte limit that Stack Overflow imposes the text continues in the below answer...

    Problem understanding the source? The assembler I used:

    • 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.
    0 讨论(0)
  • 2020-11-27 08:39

    Inputting text using int 21h AH=08h

    All three input methods described until now (in the above answer!) were clearly tailor-made to suit Microsoft tools like EDLIN.EXE and COMMAND.COM.
    If you are writing your own application then better results can be achieved through producing your own input procedure. At the heart of such a procedure will be one of the DOS single character input functions. I chose the STDIN Input function 08h because I want to allow ctrlC/ctrlBreak checking and I intend to echo the characters myself via BIOS Int 10h AH=09h Write Character And Attribute At Cursor Position. This way I can avoid messing up any redirected output.

    Programmatically there's no difference in using this BufferedInput procedure or the DOS.BufferedInput system call. However for the user at the keyboard inputting will be much easier since all the keys associated with the old and difficult template editing have been dismissed and replaced by the usual editing keys that enable you to freely move the cursor around.

    • Left Moves cursor left.
    • Right Moves cursor right.
    • Home Moves cursor to the far left.
    • End Moves cursor to the far right.
    • CtrlHome Removes all characters to the left.
    • CtrlEnd Removes all characters to the right.
    • Delete Removes the current character.
    • Backspace Removes the character to the left of the cursor.
    • Escape Removes all the characters.
    • Return Ends input.

    If the 2nd byte of the input buffer holds a non-zero value then the storage space is supposed to contain an old string (perhaps from a previous input). DOS would have called this the template. Different from DOS is that:

    • the old string is not required to be carriage return terminated.
    • the old string is immediately shown on screen.

    While the input is in progress, tabs are not expanded and the input is confined to staying within the current row. Longer texts will scroll horizontally.
    When the input is finally done, the completed text is written once with tab expansion (on screen, the storage space will always hold ASCII 9) and no longer restricted to a single row.

    This procedure does ctrlC/ctrlBreak checking.

    When this procedure finishes, the cursor will be in the far left column on the current row.

    This procedure was written with input redirection and output redirection in mind, and thus well suited for console applications.
    One effect of input redirection is that it's useless to echo any temporary output to the screen. Either the user is not there to gaze at the screen or the temporary output will be gone in the blink of an eye.

    Example 4, Improved Buffered STDIN input.

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

    Problem understanding the source? The assembler I used:

    • 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.

    For a really high performing input procedure, look at Rich Edit Form Input, a Code Review contribution.

    0 讨论(0)
提交回复
热议问题