Как сделать строковый ввод на ассемблере? - PullRequest
7 голосов
/ 21 июля 2011

Пожалуйста, кто-нибудь знает, как кодировать ввод строки на языке ассемблера? Я использую int 21 для отображения и ввода символов.

Ответы [ 2 ]

7 голосов
/ 21 июля 2011

Вы можете использовать функцию 0Ah для чтения буферизованного ввода.Имея строковый буфер в ds:dx, он читает строку длиной до 255. Макет буфера:

Byte 0 String length (0-255)
Byte 1 Bytes read (0-255, filled by DOS on return)
Bytes 2-..Length+2 (The character string including newline as read by DOS).

Пример небольшого COM-файла, который читает строку и затем выводит ее обратно вuser:

    org 0x100

start:
    push cs
    pop ds ; COM file, ds = cs

    mov ah, 0x0A ; Function 0Ah Buffered input
    mov dx, string_buf ; ds:dx points to string buffer
    int 0x21

    movzx si, byte [string_buf+1] ; get number of chars read

    mov dx, string_buf + 2 ; start of actual string

    add si, dx ; si points to string + number of chars read
    mov byte [si], '$' ; Terminate string

    mov ah, 0x09 ; Function 09h Print character string
    int 0x21 ; ds:dx points to string

    ; Exit
    mov ax, 0x4c00
    int 0x21

string_buf: 
    db 255 ; size of buffer in characters
    db 0 ; filled by DOS with actual size
    times 255 db 0 ; actual string

Обратите внимание, что он перезапишет строку ввода (и, следовательно, может не выглядеть, что программа что-то делает!)

В качестве альтернативы вы можете использовать function 01h и читайте символы самостоятельно в цикле.Примерно так (обратите внимание, что более поздние буферы будут переполнены, если введено более 255 символов):

    org 0x100

start:
    push cs
    pop ax
    mov ds, ax
    mov es, ax; make sure ds = es = cs

    mov di, string ; es:di points to string
    cld ; clear direction flag (so stosb incremements rather than decrements)
read_loop:
    mov ah, 0x01 ; Function 01h Read character from stdin with echo
    int 0x21
    cmp al, 0x0D ; character is carriage return?
    je read_done ; yes? exit the loop
    stosb ; store the character at es:di and increment di
    jmp read_loop ; loop again
read_done:
    mov al, '$'
    stosb ; 'Make sure the string is '$' terminated

    mov dx, string ; ds:dx points to string
    mov ah, 0x09 ; Function 09h Print character string
    int 0x21

    ; Exit
    mov ax, 0x4c00
    int 0x21

string: 
    times 255 db 0 ; reserve room for 255 characters
1 голос
/ 21 июля 2011

Строка - это просто последовательность символов, поэтому вы можете использовать свой код int 21 внутри цикла, чтобы получить строку, по одному символу за раз.Создайте метку в сегменте данных для хранения вашей строки, и каждый раз, когда вы читаете символ, копируйте его в эту метку (увеличивая смещение каждый раз, чтобы ваши символы сохранялись последовательно).Прекратите зацикливание, когда читается определенный символ (возможно, введите).

Делать все это вручную утомительно (подумайте, как будет работать backspace), но вы можете это сделать.В качестве альтернативы вы можете связываться с stdio, stdlib и т. Д. И вызывать библиотечные функции, чтобы выполнить большую часть работы за вас.

...