汇编语言.实验4

标志位的符号表示

取自课件

实验任务1

源代码

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

问题

不可以,第28行中调用的指令是adc,这个指令会在将两个操作数相加的同时,加上进位标识符CF中的值。出于这种目的,如果在给sidi进行运算时,改变了进位运算符的值,就会导致运算结果出错。

调试

运行前

运行后

实验任务2

源代码

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

调试

问题

问题1

利用int 21h的1号子功能,读入一个字符,放在数据段中偏移地址为si的字节处,然后将其与#作比较,如果两者相等(对应着影响到标志位ZF),就跳转到next处运行,否则自加一继续读入字符。

问题2

利用int 21h的2号子功能,根据dl中的十六进制的ASCII码,打印一个字符。这里打印的是换行。

问题3

首先根据代码段s1处对读入字符的计数,判定要输出的字符的个数,放到cx中以决定循环要执行的次数。将si置0,从数据段开始处进行处理。首先,设置int 21h的2号子功能。然后读入偏移地址处的一个字节型字符,将其输出。最后让si自加一,再次循环。

实验任务3

源代码

assume cs:code, ds:data, ss:stack
data segment
        x dw 91, 792, 8536, 65521, 2021
        len equ $ - x
data ends

stack segment
        db 16 dup(' ')
stack ends


code segment
start:  
        ;data
        mov ax, data
        mov ds, ax
        ;stack
        mov ax, stack
        mov ss, ax
        mov sp, 16

        mov si, 0
        mov cx, 5
s:      mov ax, [si]
        mov di, 0
        call printNumber
        call printSpace

        inc si
        inc si
        loop s

        mov ah, 4ch
        int 21h

printNumber:
        mov dx, 0
        mov bx, 10
        div bx

        cmp ax, 0
        je s1

        or dl, 30h
        push dx

        inc di
        jmp printNumber

s1:     mov bx, cx
        or dl, 30h
        push dx
        inc di

        mov cx, di
s2:     pop dx
        mov ah, 2
        int 21h
        loop s2
        
        mov cx, bx
        ret

printSpace:
        mov ah, 2
        mov dl, ' '
        int 21h

        ret

code ends
end start

注意点:

  1. len的长度是x的字节数,这里偷懒就直接用5代替len
  2. printNumber读取结束准备输出之前要把数据压进栈

调试

实验任务4

源代码

assume cs:code, ds:data, ss:stack
data segment
        str db "assembly language, it's not difficult but tedious"
        len equ $ - str
data ends
stack segment
        db len dup(' ')
code segment
start: 
        mov ax, data
        mov ds, ax
        mov si, 0
        mov cx, len
        call strupr

        mov ah, 4ch
        int 21h


strupr: 
s0:     mov dl, [si]
        cmp dl, 'a'

        jae toUpper

s:      mov ah, 2
        int 21h

        inc si
        loop s0
        ret

toUpper:
        and dl, 0dfh
        jmp s

code ends
end start

这里没有用到stack

调试

实验任务5

源代码

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

实验任务6

对中断的理解

进程的基本状态有就绪、运行、阻塞,在我看来,中断应该就是导致程序进入阻塞状态的原因之一。当遇到阻塞时,系统会保存运行环境,转而去运行另外的程序。int 21h4c子功能表示该程序运行结束,进入就绪状态,这时导致阻塞的原因即中断去转而实现的程序也运行结束,那么原来的程序就可以继续运行。在此看来,中断程序就是一种程序,当他被唤起时,就会立即占用处理器的资源,直到自己运行结束归还资源。

posted @ 2021-12-07 22:51  萤追月  阅读(77)  评论(1编辑  收藏  举报