• 汇编学习笔记(11)int指令和端口


    格式

    int指令也是一种内中断指令,int指令的格式为int n,n是中断类型码。也就是说,使用int指令可以调用任意的中断例程,例如我们可以显示的调用0号中断例程,还记得在汇编学习笔记(10)中我们自己定义了除法溢出的例程么,我们在这里直接调用看看

     1 assume cs:codesg
     2 
     3 codesg segment
     4     
     5 start:  
     6     mov ax,0b800h
     7     mov es,ax
     8     mov byte ptr es:[11*160+40*2],'h'
     9     int 0
    10 
    11 codesg ends
    12 
    13 end start

    成了,perfect!

    既然可以随时随地的调用中断例程,那么就可以借助中断例程来完成一些系统必须的子程序,下面是书上的例子,当次搬运工

     1 ;编写7ch号中断例程,计算word型数据的平方
     2 assume cs:codesg
     3 
     4 codesg segment
     5     
     6 start:  
     7     ;ds:si指向sqr
     8     mov ax,cs
     9     mov ds,ax
    10     mov si,offset sqr
    11     ;es:di指向0000:01e0
    12     mov ax,0000
    13     mov es,ax
    14     mov di,01e0h
    15     ;安装
    16     mov cx,offset sqrend-offset sqr
    17     cld
    18     rep movsb
    19     ;设置中断向量表
    20     mov ax,0000
    21     mov es,ax
    22     mov word ptr es:[7ch*4],01e0h
    23     mov word ptr es:[7ch*4+2],0
    24     mov ax,8888
    25     int 7ch 
    26     
    27     mov ax,4c00h
    28     int 21h
    29 sqr:
    30     mul ax
    31     iret
    32 sqrend:
    33     nop
    34     
    35 codesg ends
    36 
    37 end start

     1 ;编写7ch号中断例程,将字符串全部转换为大写
     2 assume cs:codesg,ds:data
     3 data segment
     4     db 'h',0
     5 data ends
     6 codesg segment
     7     
     8 start:  
     9     ;ds:si指向sqr
    10     mov ax,cs
    11     mov ds,ax
    12     mov si,offset upper
    13     ;es:di指向0000:01e0
    14     mov ax,0000
    15     mov es,ax
    16     mov di,01e0h
    17     ;安装
    18     mov cx,offset upperend-offset upper
    19     cld
    20     rep movsb
    21     ;设置中断向量表
    22     mov ax,0000
    23     mov es,ax
    24     mov word ptr es:[7ch*4],01e0h
    25     mov word ptr es:[7ch*4+2],0
    26     mov ax,data
    27     mov ds,ax
    28     mov si,0
    29     mov cl,11
    30     ;显示原始字符串
    31     call display
    32     ;调用中断程序
    33     int 7ch
    34     ;大写
    35     call upper 
    36     mov cl,12
    37     ;显示改写后的字符串
    38     call display
    39     
    40     mov ax,4c00h
    41     int 21h
    42 upper:
    43     push cx
    44     push si
    45 change:
    46     mov cl,[si]
    47     mov ch,0
    48     jcxz s0
    49     and byte ptr [si],11011111b
    50     inc si
    51     jmp short change
    52 s0: 
    53     pop si
    54     pop cx
    55     iret
    56 upperend:
    57     nop
    58     
    59 display:
    60     push ax
    61     push es
    62     push di
    63     push si
    64     push cx
    65     mov ax,0b800h
    66     mov es,ax
    67     mov ax,160
    68     mul cl
    69     add ax,80
    70     mov di,ax
    71     mov ch,0
    72 s1:
    73     mov cl,ds:[si]
    74     jcxz ok
    75     mov byte ptr es:[di],cl
    76     add di,2
    77     inc si
    78     jmp short s1
    79 ok:
    80     pop cx
    81     pop si
    82     pop di
    83     pop es
    84     pop ax
    85     ret
    86 codesg ends
    87 
    88 end start

    中断例程实现loop指令

    中断例程实现loop指令需要完成以下功能:

    1.(cx)=(cx)-1
      2.如果(cx)!=0,循环执行,否则向下继续执行

    为了完成上述的两种功能,显然中断例程必须获取cs和ip的值。因调用中断例程是现将cs、ip入栈,所以只需将ip的值减去循环体的长度就可以了

     1 assume cs:code
     2 
     3 code segment
     4 
     5 start:
     6     mov ax,cs
     7     mov ds,ax
     8     mov si,offset looper
     9     mov ax,01e0h
    10     mov es,ax
    11     mov di,0
    12     mov cx,offset l-offset looper
    13     cld
    14     rep movsb
    15     mov ax,0
    16     mov es,ax
    17     mov word ptr es:[7ch*4],01e0h
    18     mov word ptr es:[7ch*4+2],0
    19     mov ax,0b800h
    20     mov es,ax
    21     mov di,12*160
    22     mov bx,offset s-offset send
    23     mov cx,80
    24 s:
    25     mov byte ptr es:[di],'!'
    26     add di,2
    27     int 7ch
    28 send:
    29     nop
    30     mov ax,4c00h
    31     int 21h
    32     
    33 looper:
    34     push bp
    35     mov bp,sp
    36     dec cx
    37     jcxz loopend
    38     add [bp+2],bx   
    39 loopend:
    40     pop bp
    41     iret
    42 l:
    43     nop
    44 code ends
    45 
    46 end start

    BIOS提供的中断例程

    BIOS提供了很多中断例程以供调用,下面举个显示字符串的例子,int 10h例程中的9号子程序

     1 assume cs:code
     2 
     3 code segment
     4 
     5 start:
     6     mov ah,2
     7     mov bh,0
     8     mov dh,5
     9     mov dl,12
    10     int 10h
    11     
    12     mov ah,9
    13     mov al,'a'
    14     mov bl,11001010b
    15     mov bh,0
    16     mov cx,3
    17     int 10h
    18     mov ax,4c00h
    19     int 21h
    20 code ends
    21 
    22 end start

    端口的读写

    端口的读写只有两种指令和寄存器可以使用

    • in 读入指令,in al 读入8位数据;in ax 读入16位数据
    • out 写入指令,out al 对端口写入8位数据;out ax写入16位数据

    CMOS RAM芯片

    CMOS芯片包含两个端口70h和71h,70h是地址端口,71h是数据端口,从CMOS RAM中读取2号单元内容程序如下

     1 assume cs:code
     2 
     3 code segment
     4 
     5 start:
     6     mov al,2
     7     out 70h,al ;表示要读取2号单元
     8     in al,71h;读取2号单元内容
     9     
    10     mov ax,4c00h
    11     int 21h
    12 code ends
    13 
    14 end start

    写入的是这样

     1 assume cs:code
     2 
     3 code segment
     4 
     5 start:
     6     mov al,2
     7     out 70h,al ;表示要写入2号单元
     8     mov al,0
     9     out 71h,al;写入0
    10     
    11     mov ax,4c00h
    12     int 21h
    13 code ends
    14 
    15 end start

    shl和shr指令

    shl是逻辑左移指令,shr是逻辑右移指令。左移的最低位和右移的最高位都用0补充,并将移出的最后一位写入CF中,不论左移还是右移,都是从最低位开始的。

    mov al,10010000
      shl al,1
      shr al,1

    左移后(al)=00100000 CF=1,右移后(al)=00010000 CF=0.左移一位相当于x=x*2,右移一位相当于x=x/2.

    显示时间

     1 assume cs:code,ds:data
     2 
     3 data segment
     4     db 'yy/mm/dd hh:mm:ss','$'
     5     index db 9,8,7,4,2,0
     6 data ends
     7 
     8 code segment
     9 
    10 start:
    11     mov ax,data
    12     mov ds,ax
    13     mov si,0
    14     mov di,0
    15     mov cx,6
    16 s:
    17     push cx
    18     ;获取需要读取的端口地址
    19     mov al,index[si]
    20     out 70h,al
    21     in al,71h
    22     
    23     mov ah,al
    24     mov cl,4
    25     ;取得十位
    26     shr ah,cl
    27     ;个位
    28     and al,00001111b
    29     ;转为字符
    30     add ah,30h
    31     add al,30h
    32     
    33     mov ds:[di],ah
    34     mov ds:[di+1],al
    35     
    36     inc si
    37     add di,3
    38     
    39     pop cx
    40     loop s
    41     ;光标显示位置
    42     mov ah,2
    43     mov bh,0
    44     mov dh,10
    45     mov dl,40
    46     int 10h
    47     ;显示ds:dx指向的字符串
    48     mov ax,data
    49     mov ds,ax
    50     mov dx,0
    51     mov ah,9
    52     int 21h
    53 
    54     
    55     mov ax,4c00h
    56     int 21h
    57 code ends
    58 
    59 end start

  • 相关阅读:
    [Everyday Mathematics]20150208
    [Everyday Mathematics]20150207
    [Everyday Mathematics]20150206
    数学基本技艺100题
    这天,白云酒楼里来了两位客人
    [Everyday Mathematics]20150205
    [Everyday Mathematics]20150204
    数学书籍阅读
    国科金发计〔2014〕86号
    [Everyday Mathematics]20150203
  • 原文地址:https://www.cnblogs.com/michaelle/p/4023326.html
Copyright © 2020-2023  润新知