实验3 转移指令跳转原理及其简单应用编程

1.实验任务1

程序ex3_3.asm源码如下::

assume cs:code, ds:data

data segment
    x db 1, 9, 3
    len1 equ $ - x

    y dw 1, 9, 3
    len2 equ $ - y
data ends

code segment
start:
    mov ax, data
    mov ds, ax

    mov si, offset x
    mov cx, len1
    mov ah, 2
 s1:mov dl, [si]
    or dl, 30h
    int 21h

    mov dl, ' '
    int 21h

    inc si
    loop s1

    mov ah, 2
    mov dl, 0ah
    int 21h

    mov si, offset y
    mov cx, len2/2
    mov ah, 2
 s2:mov dx, [si]
    or dl, 30h
    int 21h

    mov dl, ' '
    int 21h

    add si, 2
    loop s2

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

 运行截图如下:

 ① line27, 汇编指令 loop s1 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机 器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明 是如何计算得到跳转后标号s1其后指令的偏移地址的。

答:位移量为14,位移量为loop指令之后的一条指令地址减去标号地址可以得出。即1B-D=E,转换为十进制为14。

② line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机 器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明 是如何计算得到跳转后标号s2其后指令的偏移地址的。

答:位移量为16,位移量为loop指令之后的一条指令地址减去标号地址可以得出。即39-29=10,转换为十进制,为16。

2.实验任务2

程序ex3_2.asm源码如下:

assume cs:code, ds:data

data segment
    dw 200h, 0h, 230h, 0h
data ends

stack segment
    db 16 dup(0)
stack ends

code segment
start:  
    mov ax, data
    mov ds, ax

    mov word ptr ds:[0], offset s1
    mov word ptr ds:[2], offset s2
    mov ds:[4], cs

    mov ax, stack
    mov ss, ax
    mov sp, 16

    call word ptr ds:[0]
s1: pop ax

    call dword ptr ds:[2]
s2: pop bx
    pop cx

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

① 根据call指令的跳转原理,先从理论上分析,程序执行到退出(line31)之前,寄存器(ax) = ? 寄存器(bx) = ? 寄存器(cx) = ?

答:程序16-17行将段s1的地址以一个字存放到ds[0]中,段s2的地址也以一个字存放到ds[2]中,然后将段stack的段地址赋给ss,栈空时,ss:sp指向栈空间最高地址单元的下一个单元,所以在该程序中,栈大小为16。程序24行,调用call指令,程序跳转到标号s1处,将下一条指令的ip入栈。在标号s1处,用ax接受栈内数据。程序27行,调用call指令,程序跳转到标号s2处,将下一条指令的cs入栈,然后将下一条指令的ip入栈。在标号s2处,分别用bx,cx接受栈内数据。

② 对源程序进行汇编、链接,得到可执行程序task2.exe。使用debug调试,观察、验证调试 结果与理论分析结果是否一致。

答:结果与理论分析结果一致。

3.实验任务3

程序ex3_3.asm源码如下:

assume cs:code, ds:data

data segment
    x db 99, 72, 85, 63, 89, 97, 55
    len equ $-x
    ;定义一个变量len并赋值$-x,$是当前地址,x是定义的变量地址。len = 7
data ends

code segment
start:
    mov ax, data
    mov ds, ax
    mov cx, len
    mov si, 0
    mov bl, 10

s:  mov ah, 0
    mov al, ds:[si]
    call printNumber
    call printSpace
    inc si
    loop s

    mov ah, 4ch
    int 21h

printNumber:
    div bl ;商为十位保存在al,余数为个位保存在ah
    mov dl, al
    mov bh, ah

    or dl, 30h
    or bh, 30h

    mov ah, 2
    int 21h

    mov dl, bh
    int 21h

printSpace:
    mov ah, 2
    mov dl, 32
    int 21h
    ret

code ends
end start

运行测试截图如下:

4.实验任务4

程序ex3_4.asm源码如下:

assume cs:code, ds:data

data segment
    str db 'try'
    len equ $ - str
data ends

code segment
start:
    mov ax, data
    mov ds, ax

    mov si, 0
    mov cx, len
    mov bl, 2
    mov bh, 0
    call printStr

    mov si, 0
    mov cx, len
    mov bl, 4
    mov bh, 24
    call printStr

    mov ah, 4ch
    int 21h

printStr:
    mov ax, 0b800h
    mov es, ax
    ;在第0页打印内容 地址空间:B8000H ~ B8F9FH

    mov al, bh
    mov bh, 0a0h
    mul bh
    mov bp, ax
    ;行数 × 160bytes 算出行偏移地址

s:  mov ah, ds:[si]
    mov es:[bp], ah ;字母信息存入低八位
    inc bp
    mov es:[bp], bl ;颜色信息存入高八位
    inc bp
    inc si
    loop s
    ret

code ends
end start

运行测试截图如下:

5.实验任务5

程序task5.asm源码如下:

assume cs:code, ds:data

data segment
    stu_no db '201983290392'
    len = $ - stu_no
data ends

code segment
start:
    mov ax, data
    mov ds, ax
    mov ax, 0b800h ;在第0页打印内容
    mov es, ax
    mov si, 0
    mov cx, 4000
    mov ah, 17h ; 蓝底白字

s1: mov al, 0
    mov es:[si], al
    mov es:[si + 1], ah
    add si, 2
    loop s1

    mov si, 3840 ;4000 - 160 = 3840
    mov cx, 34 ;(160 - 12 * 2) / 2 / 2 = 34

s2: call printDash
    add si, 2
    loop s2

    mov si, 3908 
    mov di, offset stu_no
    mov cx, len

s3: call printStuNo
    inc di
    add si, 2
    loop s3

    mov si, 3932
    mov cx, 34

s4: call printDash
    add si, 2
    loop s4

    mov ah, 4ch
    int 21h

printDash:
    mov al, '-'
    mov es:[si], al
    mov es:[si + 1], ah
    ret

printStuNo:
    mov al, [di]
    mov es:[si], al
    mov es:[si + 1], ah
    ret

code ends
end start

运行测试截图如下:

 实验总结

通过此次实验,多次使用了call和ret指令,对这两条指令的理解与使用更加深刻,同时在此次实验中,多次使用汇编语言编写输出程序,同时加深了对80*25彩色字符显示的理解。

posted @ 2021-11-27 17:03  料理机呀  阅读(44)  评论(3)    收藏  举报