汇编实验
- 实验4 分支程序设计
- 实验5 循环程序设计
实验4 分支程序设计
一、实验目的
理解分支程序结构的特点,掌握分支结构程序的编写。
二、实验内容
(1)验证单分支结构的字母判断程序(教材例4-10),编写数字判断程序(教材习题4.17),并运行正确。
(2)验证双分支结构的显示数据最高位程序(教材例4-11),编写测试高低位程序(教材习题4.16),并运行正确。
(3)(选作)参考教材附录A调试分支程序(例4-5)的方法,在WinDbg中调试自己编写的本实验①和②要求的程序(教材习题4.17和4.16),注意状态标志、跟踪指令执行顺序(即,程序指针EIP的数值变化)。
三、实验分析
画出自己编写实现的实验内容①和②的程序流程图,给出核心代码及注释。如果完成了选作内容③,请给出代表性的截图。
(1)A.验证单分支结构的字母判断程序:
代码:
include io32.inc
.data
.code
start:
call readc ;输入一个字符,从AL返回值
cmp al,'A' ;与大写字母A比较
jb done ;比大写字母A小,不是大写字母,转移
cmp al,'Z' ;与大写字母Z比较
ja done ;比大写字母Z大,不是大写字母,转移
or al,20h ;转换为小写
call dispcrlf ;回车换行
call dispc ;显示小写字母 编译运行:
done:
exit 0
end start
B.数字判断程序
代码:
include io32.inc
.data
plmsg byte 'Input Number:0~9:',13,10,0;提示输入信息
ermsg byte 'Error!',13,10,0;错误信息
.code
mov eax,offset plmsg ;
call dispmsg ;显示子程序
start:
call readuib
cmp eax,0 ;和0比较
jb no ;小于0,跳转
cmp eax,9 ;和9比较
ja no ;大于9,跳转
jmp done
no: mov eax,offset ermsg ;
call dispmsg
jmp start ;继续输入
done:
exit 0
end start
编译运行:
(2)A.验证双分支结构的显示数据最高位程序
代码:
include io32.inc
.data
dvar dword 0bd630422h ;假设一个数据
.code
start:
mov ebx,dvar
shl ebx,1 ;ebx最高位移入CF标志
jc one ;CF=1,即最高位为1,转移
mov al,'0' ;CF=0,即最高位为0;AL=‘0’
jmp two ;一定要跳过另一个分支体
one: mov al,'1' ;AL=‘1’
two: call dispc ;显示
done:
exit 0
end start
编译运行:
B.测试高低位程序
代码:
include io32.inc
.data
dvar dword 57h ;定义一个双字变量值为57h
.code
start:
mov eax,dvar ;eax=57h
test eax,80000000h ;测试最高位
jnz nextl ;最高位为1则跳转至nextl,否则顺序执行
test eax,1 ;测试最低位
jnz nextr ;最低位为1则跳转至nextr,否则顺序执行
mov al,'M' ;al='M'
jmp done ;无条件转移至done
nextl: mov al,'L' ;al='L'
jmp done ;无条件转移至done
nextr: mov al,'R' ;al='R'
done:
call dispc ;输出al
exit 0
end start 编译运行:
编译运行结果:
程序流程图:
a.数字判断程序
b.测试高低位程序
(3)在WinDbg中调试自己编写的本实验①和②要求的程序
A.数字判断程序
初始寄存器窗口:
运行结束寄存器窗口:
存储器窗口:
Watch 窗口:
反汇编窗口:
B.测试高低位程序
寄存器窗口:
反汇编窗口:
Watch 窗口:
存储器窗口:
实验5 循环程序设计
一、实验目的
理解循环程序结构的特点,掌握循环结构程序的编写。
二、实验内容
(1)验证循环结构的斐波那契数列程序(教材例4-18),给出最后一个显示的数字。编写求最大N值的自然数求和程序(循环结构),具体要求是:进行自然数相加(1+2+3+……+N),如果(无符号整数的)累加和用一个32位寄存器存储,求出(显示)有效累加和的最大值及对应的最大N值。
(2)验证多重循环的冒泡法排序程序(教材例4-19),编写显示ASCII表程序(教材习题4.27),并运行正确。
(3)(选作)参考教材附录A调试循环程序(例4-15)的方法,在WinDbg中调试自己编写的本实验①和②要求的程序(求最大N值和教材习题4.27),注意灵活运用单步进入(Step Into)和单步通过(Step Over)的调试手段。
三、实验分析
画出自己编写实现的实验内容①和②的程序流程图,给出核心代码及注释。如果完成了选作内容③,给出代表性截图。
(1)A.斐波那契数列程序
代码:
include io32.inc
.data
.code
start:
mov eax,1 ;首元素为1
call dispuid ;显示元素
call dispcrlf ;换行
call dispuid ;显示元素
call dispcrlf ;换行
mov ebx,eax ;次元素也为1
again:
add eax, ebx ;前二元素加和
jc done ;超出32位进位范围为止
call dispuid ;显示元素
call dispcrlf ;换行
xchg eax,ebx ;eax和ebx数据互换,进行下一轮累加和
jmp again
done: exit 0
end start
运行结果:
B.求最大N值的自然数求和程序
代码:
include io32.inc
.data
overmsg byte 'The SUM and N is: '
.code
start: mov eax,1 ;设置初始值
mov ebx,0
again:
mov ecx,eax
add eax,ebx ;前一个数和后一个数累加
jc over ;判断是否进位,进位则跳转
call dispuid
call dispcrlf
inc ebx
jmp again ;再执行again循环
over:
mov eax, offset overmsg ;汇报越界语句
call dispmsg
dec ecx
mov eax, ecx ;汇报越界前有效累加最大和
call dispuid
call dispcrlf
dec ebx
mov eax, ebx ;汇报对应的最大N值
call dispuid
done: exit 0
end start
运行结果:
(2)多重循环的冒泡法排序程序
代码:(添加了输出)
include io32.inc
.data
array dword 587,-632,777,234,-34
count = lengthof array
.code
start: mov ecx,count
dec ecx ;外循环起始次数为length-1
outcir: mov edx,ecx ;外循环起始
mov ebx,offset array ;数组指针
incir: mov eax,[ebx] ;按ebx中的地址去存储单元取数据
cmp eax,[ebx+4]
jng next ;如果arr[j]<arr[j+1],不交换位置
xchg eax,[ebx+4] ;否则交换位置
mov [ebx],eax ;完成位置交换
next: add ebx,4 ;下一个元素
dec edx ;内循环计数
jnz incir ;判断某一轮外循环中的内循环是否结束
loop outcir
ok: mov ecx,count
mov ebx,offset array
print: mov eax,[ebx]
call dispsid
call dispcrlf
add ebx,4
loop print
done: exit 0
end start
运行结果:
C.显示ASCII表程序
include io32.inc
.data
onemsg byte ' | 0 1 2 3 4 5 6 7 8 9 A B C D E F', 13,10 ;第一行内容
byte '--- + ', 31 dup ('-'),13,10,0
msg3 byte ' ',0
msg4 byte ' | ',0
msgtry byte 'here',0
priarr byte ?
.code
start: mov eax, offset onemsg
call dispmsg
mov ebx,0
mov edx,020h ;初始化
outcir: mov eax,offset msg3
call dispmsg
mov eax,edx
call disphb ;显示前面的部分
mov eax,offset msg4
call dispmsg
incir:cmp ebx,0fh ;判断该行打印条件
ja next ;大于15,顺序执行
mov eax,ebx ;否则打印该字符
add eax,edx
call dispc ;逐个打印字符
mov eax,020h ;打印ACSII间的空格
call dispc
inc ebx ;计数器
jmp incir
next: call dispcrlf
;mov eax,offset msgtry
;call dispmsg
add edx,010h ;外循环每次自增010h
cmp edx,070h ;外循环结束条件
ja done;大于则结束
mov ebx,0;否则再次进入外循环
jmp outcir
done: exit 0
end start
运行结果:
流程图:
求最大N值的自然数求和程序
D.E.显示ASCII表程序
(3)A.反汇编窗口:
B寄存器窗口
存储器窗口