汇编语言第十三章 int 指令 小白笔记

文章详细介绍了在Intelx86架构下如何使用int指令调用中断,包括求平方的中断例程实现和大写转小写的处理。此外,通过7ch中断模拟loop指令在屏幕上显示特定字符,并讨论了栈在中断处理中的作用和iret指令的使用。
摘要由CSDN通过智能技术生成

13.1 int 指令

int指令:其实就是转到对应的中断指令

int n

过程:

(1)取中断码

(2)标志寄存器入栈,IF=0,TF=0

(3)CS,IP入栈

(4)(IP)=(n*4),(CS)=(n*4+2)

assume cs:code
code segment

    start:mov ax,0b800h
    mov es,ax
    mov byte ptr es:[12*160+40*2],'!'
    int 0

code ends
end start

winxp执行

13.2 编写供应用程序调用的中断例程(中断程序)

问题一求平方:

;求ax平方  高16位放到DX,低16为放到AX中
assume cs:code 

code segment
    start: mov  ax,cs
           mov  ds,ax
           mov  si,offset sqr                   ;ds:si指向源地址
           mov  ax,0
           mov  es,ax
           mov  di,200h                         ;es:di指向目的地址
           mov  cx,offset sqrend -offset sqr    ;设置cx

           cld                                  ;正向传输
           rep  movsb

           mov  ax,0
           mov  es,ax
           mov  word ptr es:[7ch*4],200h
           mov  word ptr es:[7ch*4+2],0
           mov  ax,1234
        
           int  7ch
           mov  ax,4c00h
           int  21h


    sqr:   mul  ax
           iret

    sqrend:nop

code ends
end start

问题二:大写转小写

(显示到屏幕是我自己添的)

assume cs:code

code segment
    start:                                                 ;将下边capital大小写转换代码看作数据转移到0000:0200的地方
               mov  ax,cs
               mov  ds,ax                                  ;因为下边想用movsb那个可以将ds:si中的内容一下子放到es:di中的厉害指令
               mov  si,offset capital                      ;因为要复制的指令(源)(机器码)在cs中,所以要将cs给ds,si就是capital对应的偏移地址,这里用offset就好啦
                                                            ;一定一定要注意的是,ds:si--->es:di因为这个错误折磨了我一上午。我把si和di写反了。
               mov  ax,0                                   ;这里就是设置目的地址了,将es:di设置到0000:0200就好
               mov  es,ax
               mov  di,200h
               mov  cx,offset capitalend-offset capital    ;这个cx嘛是要复制数据的长度用偏移地址相减就欧克
               cld                                         ;不能让他倒着复制要不然就麻烦了,这条指令是设置正着复制的
               rep  movsb                                  ;一把梭哈,一步到位,这条指令就是那个特别厉害的指令,可以一口气将cx
                                                            ;长度的机器码(就是内存中的内容)复制到es:di中,,记住是ds:si--->es:di


               mov  ax,0                                   ;这里是设置7ch中断的,将中断例程和地址对应起来
                                                            ;专业点好像是叫将7ch中断例程的段地址和偏移地址写到中断向量表中
               mov  es,ax
               mov  word ptr es:[7Ch*4],200h
               mov  word ptr es:[7Ch*4+2],0
               
               
               int  7CH                                    ;调用7ch中断例程


               mov  ax,4c00h
               INT  21H
              





    capital:   push cx                                     ;将用到的寄存器保护起来和下边的pop对应
               push si
               push ax
               push ds
               push cs
               push es
               push bp
            
               jmp  short change                           ;这里是数据,因为不是指令所以不能让他执行,要跳过
               db   'llllll'
               db   'oooooooooooooo',0


    change:    mov  ax,0b800h                              ;设置一下用到的寄存器,不可以在change里设置,
                                                            ;因为跳转的时候会重新设置,这样就会一直读取一个东西或者写入到一个地方
               mov  es,ax
               mov  bp,160*12+2*40                         ;我想让他写到这里,将转换后的数据
               mov  ax,0
               mov  si,209h                                ;这个是刚刚数据存放的地址,可以从200开始数,反正我是数的

    change2:   mov  cl,cs:[si]                             ;将读入的数据放到cl中,因为要一个一个的转换,一个字母是8为,一个字节,对应半个16位寄存器
               mov  ch,0                                   ;将ch=0,这样cl=0一定就会使cx=0,下边的jcxz才好使
               jcxz ok                                     ;如果读到0了就跳转到不向下执行了直接到ok

               and  byte ptr cs:[si],11011111b             ;这个就是让小写变成大写的指令,当然不止一个,但是这里用这个吧,因为书上用的这个

               
               mov  al,cs:[si]                             ;转换后我想看看有没有成功,久让他在屏幕上显示了
               mov  es:[bp],al
               add  bp,2                                   ;因为显示到屏幕是偶数是内容,奇数是属性,我们不用设置属性直接跳过加2
               
               inc  si                                     ;读取下一个字母
               
               jmp  short change2                          ;跳转到change2
    ok:        
    
               pop  bp
               pop  es
               pop  ax
               mov  cs,ax
               pop  ds
               pop  ax
               pop  si
               pop  cx
              
               iret                                        ;和call对应ret类似,int要对应iret好一点

    capitalend:nop

code ends
end start

结果

13.3对·int、iret和栈的深入理解

问题:用7ch中断完成loop指令功能

在屏幕显示80个“!”

assume cs:code

code segment
    start:                                    ;安装7ch
          mov  ax, cs
          mov  ds,ax
          mov  si,offset lp

          mov  ax,0
          mov  es,ax
          mov  ax,200h
          mov  di,ax
    
          mov  cx,offset lpret-offset lp+2    ;刚开始不行怀疑是没有安装全,+1也不行,+2才可以
          cld
          rep  movsb
    ;设置中断向量表
          mov  word ptr es:[7ch*4],200h
          mov  word ptr es:[7ch*4+2],0h
    ;显示!到屏幕
          mov  ax,0b800h
          mov  es,ax
          mov  di,160*12
    ;用bx保存偏移地址
          mov  bx,offset s-offset se

          mov  cx,80
    ;
    s:    mov  byte ptr es:[di],'!'
          add  di,2
          int  7ch

    se:   nop

          mov  ax,4c00h
          int  21h


    ;把用到的寄存器保护起来
    ;这个时候栈的情况是这样的
    ;bp
    ;se的ip   ss*16+bp+2
    ;se的cs
    ;bp是用来保存栈顶的sp的


    lp:   push bp
          mov  bp,sp                          ;将sp给到bp
          dec  cx
          jcxz lpret                          ;cx!=0就跳转,也就是不更改cs:ip
          add  [bp+2],bx
    lpret:pop  bp
          iret                                ;出栈,如果更改了,就出栈更改后的,没有更改就是之前的,就不会循环了


code ends

    end start

结果:

监测点13.1

将data段(以0结尾)的数据,显示到屏幕上

assume cs:code
data segment
         db 'conversation',0
data ends

code segment
    start:
    
    
    ;安装7ch
          mov ax, cs
          mov ds,ax
          mov si,offset lp

          mov ax,0
          mov es,ax
          mov ax,200h
          mov di,ax
    
          mov cx,offset lpret-offset lp+2    ;刚开始不行怀疑是没有安装全,+1也不行,+2才可以
          cld
          rep movsb
    ;设置中断向量表
          mov word ptr es:[7ch*4],200h
          mov word ptr es:[7ch*4+2],0h
    
    
    
    
    
    
          mov ax,data
          mov ds,ax
          mov si,0
          mov ax,0b800h
          mov es,ax
          mov di,12*160
    s:    cmp byte ptr [si],0
          je  ok
          mov al,[si]
          mov es:[di],al
          inc si
          add di,2
          mov bx,offset s-offset ok
          int 7ch
    ok:   mov ax,4c00h
          int 21h





    ;把用到的寄存器保护起来
    ;这个时候栈的情况是这样的
    ;bp
    ;se的ip   ss*16+bp+2
    ;se的cs
    ;bp是用来保存栈顶的sp的


    lp:   push bp
          mov  bp,sp                          ;将sp给到bp
          add  [bp+2],bx
    lpret:pop  bp
          iret                                ;出栈,如果更改了,就出栈更改后的,没有更改就是之前的,就不会循环了




          

code ends
end start

结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

y6y6y666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值