【问题标题】:How to make string input in Assembly language?如何用汇编语言进行字符串输入?
【发布时间】:2011-10-10 11:23:50
【问题描述】:

请问,有人知道如何用汇编语言对字符串输入进行编码吗?我正在使用int 21 来显示和输入字符。

【问题讨论】:

    标签: user-input dos assembly


    【解决方案1】:

    字符串只是一系列字符,因此您可以在循环内使用 int 21 代码来获取字符串,一次一个字符。在数据段中创建一个标签来保存您的字符串,每次读取一个字符时,将其复制到该标签(每次增加一个偏移量,以便您的字符按顺序存储)。读取某个字符时停止循环(可能是输入)。

    手动完成所有这些工作很乏味(想想退格是如何工作的),但您可以做到。或者,您可以链接到 stdio、stdlib 等并调用库函数来为您完成大部分工作。

    【讨论】:

    • 非常感谢。但我不知道,如何做到这一点。我知道它会像mov ah, 1h
    • 我无法编辑该帖子。非常感谢。但我不知道,如何做到这一切。我不知道如何在标签中插入更多字符。所以我将拥有string db "$$$",现在呢?我可以mov string, al ; pressed character to db吗?如果是,那么下一步该做什么?我不知道如何增加字符位置...你能把示例代码放在这里吗?
    • 希望这仍然对您有用。您可以将内存位置保存在寄存器中,而不是使用标签。这样,您写入寄存器中的内存地址,而不是每次都写入标签。然后,当您修改地址寄存器(为每个字符递增)时,您将写入新的内存位置。
    【解决方案2】:

    您可以使用function 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 文件示例:

        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
    

    【讨论】:

    • 如果您想要一个仅包含“$”(ah=09h 函数的终止符)的单字节字符串,可以,但是没有任何地方可以存储您读取的字符。 times 255 db 与 db 0, 0, 0, 0, [snip 250 times 0,], 0 相同,确保有空间存储字符。如果您使用不同的汇编器,保留空间的语法可能会有所不同(和/或您可以使用动态内存分配)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多