一. 实验目的
掌握在集成开发软件环境中汇编程序的编写、调试方法。所用开发环境为TPC-ZK-II。
二. 实验内容
实验1-1-1
在以BUF为首地址的字节存储区存放有若干个无符号数,求该序列中的最大值,并在屏幕上输出该最大值。输入如下源程序并运行,查看运行结果。要求:了解汇编指令,学会单步调试。
汇编代码:
stack segment stack
db 200 DUP(?)
stack ends
data segment
buf db 12h,22h,4h,15h,9h,63h,1h,60h,62h ;buf存储区存放了9个无符号数,输出其对应ASCII码的字符
N equ $-BUF ;N为buf存储区中的数据个数
max db ? ;max为buf存储区中最大的数据,尚未赋值
min db ? ;min为buf存储区中最小的数据,尚未赋值
data ends
code segment
assume cs:code,ds:data,ss:stack
start:
mov ax,data ;将data数据段送入ax寄存器中暂存
mov ds,ax ;将ax寄存器中的数据送入ds中
mov si,offset buf ;取得buf数据存储区的首地址并送入si寄存器中
mov cx,N ;将数据个数N送入cx寄存器中
call maxmin ;调用maxmin子程序
mov cl,bh ;将bh中存放的最大值送入cl中
mov ah,02h ;调用DOS的2号功能
mov dl,cl ;将cl寄存器中的值送入al中
int 21h ;中断,输出
mov ax,4c00h ;返回DOS
int 21h ;中断,退出
maxmin proc ;maxmin子程序开始定义
push ax ;将ax中的数据送入栈中
mov bh,[si] ;取得buf数据存储区中的数据送入bh中
mov bl,bh ;将bh中的数据送入bl中
dec cx ;cx中的数据减一
A1:
inc si ;si自增,遍历data数据段
mov al,[si] ;取得buf数据存储区中的数据送入al中
cmp al,bh ;比较al中的数据是否大于bh数据
jle a3 ;如果al中的数据大于bh中数据则跳转至A3,需要更新最大数bh的值
A2:
mov bh,al ;将al寄存器中数据送入存最大数据的bh寄存器中
A3:
loop A1 ;循环A1操作
pop ax ;将ax中的数据弹出栈外
ret ;修改IP实现近转移
maxmin endp ;maxmin子程序结束定义
code ends
end start
运行结果:
输出最大值对应的ASCII码字符“c”。
实验1-1-2
在实验1-1-1的基础上,添加修改代码补充程序,要求能同时求出最大值和最小值,并输出。
汇编代码:
stack segment stack
db 200 DUP(?)
stack ends
data segment
buf db 12h,22h,4h,15h,9h,63h,1h,60h,62h ;buf存储区存放了9个无符号数,输出其对应ASCII码的字符
N equ $-BUF ;N为buf存储区中的数据个数
max db ? ;max为buf存储区中最大的数据,尚未赋值
min db ? ;min为buf存储区中最小的数据,尚未赋值
data ends
code segment
assume cs:code,ds:data,ss:stack
start:
mov ax,data ;将data数据段送入ax寄存器中暂存
mov ds,ax ;将ax寄存器中的数据送入ds中
mov si,offset buf ;取得buf数据存储区的首地址并送入si寄存器中
mov cx,N ;将数据个数N送入cx寄存器中
call maxmin ;调用maxmin子程序
mov max,bh ;将存放最大值的bh寄存器中的数据送入max存储
mov min,bl ;将存放最小值的bl寄存器中的数据送入min存储
mov ah,02h ;调用DOS的2号功能
mov dl,max ;2号功能调用,输出最大值max
int 21h ;中断,输出信息
mov ah,02h ;调用DOS的2号功能
mov dl,min ;2号功能调用,输出最小值min
int 21h ;中断,输出信息
mov ax,4c00h ;返回DOS
int 21h ;中断,退出
maxmin proc ;maxmin子程序开始定义
push ax ;将ax中的数据送入栈中
mov bh,[si] ;取得buf数据存储区中的数据送入bh中
mov bl,bh ;将bh中的数据送入bl中
dec cx ;cx中的数据减一
A1:
inc si ;操作数si自增,遍历data数据段
mov al,[si] ;取得buf数据存储区中的数据送入al中
cmp al,bh ;比较al中的数据和bh中的数据
jbe a2 ;若al不大于bh,即bh最大值不变,跳转至A2操作
mov bh,al ;否则al大于bh,说明al中的数据比bh还大,需要用al中的数据替换bh中的最大值
jle a3 ;若al不大于bh,data数据段尚未遍历完全,跳转至A3操作
A2:
cmp al,bl ;比较al中的数据是否大于bl数据
jae a3 ;如果al大于等于bl,则bl最小值不变,继续遍历data,跳转至A3操作
mov bl,al ;否则al小于bl,说明al中的数据比bl还小,需要用al中的数据替换bl中的最小值
A3:
loop A1 ;循环A1操作
pop ax ;将ax中的数据弹出栈外
ret ;修改IP实现近转移
maxmin endp ;maxmin子程序结束定义
code ends
end start
运行结果:
输出最大值和最小值对应的ASCII码字符“c”和“☺”。
实验1-2-1
从键盘上输入一个字符,如果输入的事大写字母,则在屏幕上输出其对应的小写字母,如果输入了除大写字母外的其他字符,提示信息。
汇编代码:
stack segment stack
db 200 dup(0)
stack ends
data segment
string db 'PLEASE INPUT AN ENGLISH LETTER!', 0ah,0dh, '$' ;定义数据存储区string,存放提示用户输入的文字
data ends
code segment
assume cs:code,ds:data,ss:stack
start:
mov ax,data ;将data数据段送入ax寄存器中暂存
mov ds,ax ;将ax寄存器中的数据送入ds中
mov ah,01h ;调用DOS的1号功能
int 21h ;中断,输出提示输入的信息string
cmp al,'A' ;将al中的数值与'A'的ASCII码值进行比较
jl exit ;若al中数值比'A'的ASCII码值小,则跳转至exit
L1:
cmp al,'Z' ;将al中的数值与'Z'的ASCII码值进行比较
jg exit ;若al中数值比'Z'的ASCII码值大,则跳转至exit子程序
add al,32 ;否则将al的值加32,将大写转换为小写,ASCII码值相差32
mov cl,al ;将al中数值送入cl中
exit1:
mov dl,cl ;将cl中数值送入dl中
mov ah,02h ;调用DOS的2号功能
int 21h ;中断,输出信息
mov ax,4c00h ;返回DOS
int 21h ;中断,退出
exit:
mov dl,0ah ;将0ah中存的string字段送入dl
mov ah,02h ;调用DOS的2号功能
int 21h ;中断,输出信息
mov ax,data ;将data数据段送入ax寄存器中暂存
mov ds,ax ;将ax寄存器中的数据送入ds中
mov dx,offset string ;取得string数据存储区的首地址并送入si寄存器中
mov ah,09h ;调用DOS的9号功能
int 21h ;中断,输出信息
mov ax,4c00h ;返回DOS
int 21h ;中断,退出
code ends
end start
运行结果:
测试大写转小写,输入“G”,输出“g”:
实验1-2-2
在实验1-2-1的基础上,添加修改代码补充程序,要求:判断输入的字符,如果是大写字母则输出其小写字母,如果输入的字符是小写字母则输出其对应的大写字母,输入其他字符则提示信息。
汇编代码:
stack segment stack
db 200 dup(0)
stack ends
data segment
string db ' PLEASE INPUT AN ENGLISH LETTER!', 0ah,0dh, '$' ;定义数据存储区string,存放提示用户输入的文字
data ends
code segment
assume cs:code, ds:data, ss:stack
start:
mov ax,data ;将data数据段送入ax寄存器中暂存
mov ds,ax ;将ax寄存器中的数据送入ds中
mov ah,01h ;调用DOS的1号功能
int 21h ;中断,输出提示输入的信息string
cmp al,'A' ;将al中的数值与'A'的ASCII码值进行比较
jl exit ;若al中数值比'A'的ASCII码值小,则跳转至exit
L1:
cmp al,'Z' ;将al中的数值与'Z'的ASCII码值进行比较
jg L2 ;若al中数值比'Z'的ASCII码值大,则跳转至L2
add al,32 ;否则说明输入的字符是大写字母(A~Z),将al的值加32,将大写转换为小写,ASCII码值相差32
mov cl,al ;将al中数值送入cl中
exit1:
mov dl,cl ;将cl中数值送入dl中
mov ah,02h ;调用DOS的2号功能
int 21h ;中断,输出信息
mov ax,4c00h ;返回DOS
int 21h ;中断,退出
L2:
cmp al,'a' ;将al中的数值与'a'的ASCII码值进行比较
jl exit ;若al中数值比'a'的ASCII码值小,则跳转至exit
cmp al,'z' ;若al中数值比'a'的ASCII码值大,则继续将al中的数值与z'的ASCII码值进行比较
jg exit ;若al中数值比'z'的ASCII码值大,则跳转至exit
sub al,32 ;否则说明输入的字符是小写字母(a~z),将al的值减32,将小写转换为大写,ASCII码值相差32
mov cl,al ;将al中数值送入cl中
exit2:
mov dl,cl ;将cl中数值送入dl中
mov ah,02h ;调用DOS的2号功能
int 21h ;中断,输出信息
mov ax,4c00h ;返回DOS
int 21h ;中断,退出
exit:
mov dl,0ah ;将0ah中存的string字段送入dl
mov ah,02h ;调用DOS的2号功能
int 21h ;中断,输出信息
mov ax,data ;将data数据段送入ax寄存器中暂存
mov ds,ax ;将ax寄存器中的数据送入ds中
mov dx,offset string ;取得string数据存储区的首地址并送入si寄存器中
mov ah,09h ;调用DOS的9号功能
int 21h ;中断,输出信息
mov ax,4c00h ;返回DOS
int 21h ;中断,退出
code ends
end start
运行结果:
测试大写转小写,输入“Z”,输出“z”:
测试小写转大写,输入“z”,输出“Z”: