汇编语言程序设计实验四:8086标志寄存器及中断

  • 实验任务1

    • task1.asm源码:
    assume cs:code, ds:data
    
    data segment
     x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h
     y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h
    data ends
    code segment 
    start:
      mov ax, data
      mov ds, ax
      mov si, offset x
      mov di, offset y
      call add128
    
      mov ah, 4ch
      int 21h
    
    add128:
      push ax
      push cx
      push si
      push di
    
      sub ax, ax
    
      mov cx, 8
    s:  mov ax, [si]
      adc ax, [di]
      mov [si], ax
    
      inc si
      inc si
      inc di
      inc di
      loop s
    
      pop di
      pop si
      pop cx
      pop ax
      ret
    code ends
    end start
    
    • 关于add指令的调试过程截图如下:

      由图可知add指令使得ZF标志位由NZ变为ZR,CF标志位由NC变为CY,可知运算结果为0且在运算中由最高位向更高位产生了进位。

    • 关于inc指令的调试过程截图如下:

      由图可知inc指令使得ZF标志位由NZ变为ZR,可知运算结果为0,而CF未曾改变。

    • line31~line34的4条inc指令,不能替换成如下代码,原因是:该题用adc指令进行大整数加法,期间需要用到CF标志位的数值,而上面已经验证过add指令会对CF标志位产生影响,故不能替换。
      add si, 2
      add di, 2

  • 128位加之前数值截图:

  • 完成128位加之后数值截图(有变化):

  • 实验任务2

    • task2.asm源码:
    assume cs:code, ds:data
    data segment
          str db 80 dup(?)
    data ends
    
    code segment
    start:  
          mov ax, data
          mov ds, ax
          mov si, 0
    s1:        
          mov ah, 1
          int 21h
          mov [si], al
          cmp al, '#'
          je next
          inc si
          jmp s1
    next:
          mov ah, 2
          mov dl, 0ah
          int 21h
          
          mov cx, si
          mov si, 0
    s2:     mov ah, 2
          mov dl, [si]
          int 21h
          inc si
          loop s2
    
          mov ah, 4ch
          int 21h
    code ends
    end start
    
    • 运行结果截图:

    • line11-18:获取键盘输入的值并赋值给ds:[si] ,若为“#”,则跳转到next处,否则si++后再次重新进入本循环。

    • line20-22:换行

    • line24-30:打印除“#”外所有用户输入的字符

  • 实验任务3

    • task3.asm源码:
    assume cs:code, ds:data
    data segment
      x dw 91, 792, 8536, 65521, 2021
      len equ $ - x
    data ends
    
    stack segment
      y dw 5 dup(?)
    stack ends
    
    code segment
    start:
      mov ax, data
      mov ds, ax
      mov ax, stack
      mov ss, ax
      mov sp, 10
      mov si, offset x
      mov cx, 5
    
    s:  mov ax, [si]
      mov di, 0
      mov bx, 10
    
    sa:   mov dx, 0
      div bx
      or dl, 30h
      push dx
      inc di
      cmp ax, 0
      jne sa
    
    s1:  mov ah, 2
      pop dx
      int 21h
      dec di
      cmp di, 0
      jne s1
    
      call s2
      inc si
      inc si
      loop s
    
      mov ah, 4ch
      int 21h
    
    s2:  mov ah, 2
      mov dl, ' '
      int 21h
      ret
    
    code ends
    end start
    
    • 运行结果截图如下:
  • 实验任务4

    • task4.asm源码:
    assume cs:code, ds:data
    
    data segment
      str db "assembly language, it's not difficult but tedious"
      len equ $ - str
    data ends
    
    code segment
    start:
      mov ax, data
      mov ds, ax
      mov si, offset str
      mov cx, len
      call s1
      mov ah, 4ch
      int 21h
    
    s1:  mov ah, 2
      mov dl, [si]
      cmp dl, 61h
      jb s2
      cmp dl, 7ah
      ja s2
      and dl, 11011111B
    
    s2:  mov [si], dl
      inc si
      loop s1
      ret
    
    code ends
    end start  
    
    • 调试截图如下:

  • 实验任务5

    • task5.asm源码:
    assume cs:code, ds:data
    
    data segment
      str1 db "yes", '$'
      str2 db "no", '$'
    data ends
    
    code segment
    start:
      mov ax, data
      mov ds, ax
    
      mov ah, 1
      int 21h
    
      mov ah, 2
      mov bh, 0
      mov dh, 24
      mov dl, 70
      int 10h
    
      cmp al, '7'
      je s1
      mov ah, 9
      mov dx, offset str2
      int 21h
    
      jmp over
    
    s1: mov ah, 9
      mov dx, offset str1
      int 21h
    over:  
      mov ah, 4ch
      int 21h
    code ends
    end start
    
    • 程序运行测试截图:

    • 程序的功能:判断用户键入的字符是否为7,是则输出“yes”,不是则输出“no”,输出位置在第24行70列。

  • 实验任务6

    • task6_1.asm源码:
    assume cs:code
    
    code segment
    start:
      ; 42 interrupt routine install code
      mov ax, cs
      mov ds, ax
      mov si, offset int42  ; set ds:si
    
      mov ax, 0
      mov es, ax
      mov di, 200h        ; set es:di
    
      mov cx, offset int42_end - offset int42
      cld
      rep movsb
    
      ; set IVT(Interrupt Vector Table)
      mov ax, 0
      mov es, ax
      mov word ptr es:[42*4], 200h
      mov word ptr es:[42*4+2], 0
    
      mov ah, 4ch
      int 21h
    
    int42: 
      jmp short int42_start
      str db "welcome to 2049!"
      len equ $ - str
    
      ; display string "welcome to 2049!"
    int42_start:
      mov ax, cs
      mov ds, ax
      mov si, 202h
    
      mov ax, 0b800h
      mov es, ax
      mov di, 24*160 + 32*2
    
      mov cx, len
    s:  mov al, [si]
      mov es:[di], al
      mov byte ptr es:[di+1], 2
      inc si
      add di, 2
      loop s
    
      iret
    int42_end:
     nop
    code ends
    end start
    
    • task6_2.asm源码:
    assume cs:code
    
    code segment
    start:
      int 42
    
      mov ah, 4ch
      int 21h
    code ends
    end start
    
    • 运行结果截图如下:

      task6_1.exe安装中断代码,task6_2.exe向CPU发出中断,最终指令42号中断程序成功调用!
  • 实验总结

    • 中断是指来自CPU执行指令以外的事件发生后,处理机暂停正在运行的程序,转去执行处理该事件的程序的过程。
    • 软中断是软件实现的中断,也就是程序运行时其他程序对它的中断。
    • 中断过程如下:
      1. 从中断信息中获取类型码;
      2. 标志寄存器的值入栈;
      3. 设置标志寄存器的TF和IF标志位为0
      4. CS的内容入栈
      5. IP的内容入栈
      6. 读取中断处理程序的入口地址IP和CS
posted @ 2021-12-14 23:45  诺晨HERE  阅读(169)  评论(1)    收藏  举报