实验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彩色字符显示的理解。

浙公网安备 33010602011771号