汇编的输入和输出

1,421 阅读2分钟

在汇编语言里面,输入输出是通过调用中断服务实现的。

现有如下需求:

输入字符,并在屏幕上输出该字符,以及该字符的ascii码,直到输出的字符为q或者Q结束程序。

data segment para 'data'
    input   db "please input a char: ",'$'
    output  db "your input is: ",'$'
    asciioutput db "the ascii of your input is: ",'$'
    crlf    db 0ah, 0dh, '$'
    char    db '?'
    ascii1   db '?'
    ascii2   db '?'
data ends

mystack segment para 'stack' 
    dw 20 dup(0)
mystack ends

code segment para 'code' 
assume cs:code, ds:data, ss:mystack
start:
    mov ax, data
    mov ds, ax

    mov dx, offset input
    mov ah, 09h
    int 21h

    mov ah, 01h
    int 21h
    mov char, al

    cmp char, 'q'
    je quit

    cmp char, 'Q'
    je quit

    mov dx, offset crlf
    mov ah, 09h
    int 21h

    mov ah, 09h
    mov dx, offset output
    int 21h

    mov dl, char
    mov ah, 02h
    int 21h

    mov al, char
    mov dl, char
    and al, 0fh
    and dl, 0f0h
    shr dl, 4

    cmp al, 0ah
    jnl L2
    add al, 7h
L2:
    add al, 30h
    mov ascii1, al

    cmp dl, 0ah
    jnl L3
    add dl, 7h 
L3:
    add dl, 30h
    mov ascii2, dl

    mov dx, offset crlf
    mov ah, 09h
    int 21h

    mov dx, offset asciioutput
    mov ah, 09h
    int 21h

    mov dl, ascii1
    mov ah, 02h
    int 21h

    mov ah, 02h
    mov dl, ascii2
    int 21h

    mov dx, offset crlf
    mov ah, 09h
    int 21h

    jmp start

quit:   
    mov ah, 4ch
    int 21h
code ends
end start 

首先定义data段的内容,就是我们需要输出的提示字符串等内容。其中db为单字,和byte类似。

crlf里面存的为换行相关的操作。

在code段里面assume只是告诉代码哪个段的内容是哪个,并没用将相关内容放入相应的寄存器。

start开始之后,那两个操作才是将data段的数据存入ds寄存器,如果没这两行,ds开头就是包含了data段以及数据头在内的所有数据,并且没法直接访问相应的数据。

输出字符串是默认从dx寄存器开始输出的,然后调用输出中断实现输出到屏幕,中断处理程序号为21h加上ah寄存器里面的值。输出中断为为09h+21h,所以为mov ah, 09h mov dx, offset input int 21h

同理打印输出字符串只要将input改为output就行了。

打印单个字符为从dl寄存器打印,调用的中断处理程序为21h+02h,代码为 mov ah, 02h mov dl, char. int 21h

输入字符为调用21h+01h,输入的字符自动存入al ,相应的代码为 mov ah, 01h int 21h mov char, al

至于ascii码的转换方法。我们观察ascii码表,我们可以发现字符0的ascii码为30h,即00110000。

我们可以推算出我们可以将字符的前四位,后四位分别加30h,其中四位如果大于0ah的话还需要加7h,最后将这两个相加后的数分别输出就为相应的ascii码了。