李北明微机原理_第1页
李北明微机原理_第2页
李北明微机原理_第3页
李北明微机原理_第4页
李北明微机原理_第5页
已阅读5页,还剩58页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

微机原理及接口技术信通学院8086的寻址方式

和指令系统(7)主讲人

李北明教学重点综合应用指令和伪指令,从程序结构角度展开程序设计,重点掌握:分支结构程序设计循环结构程序设计子程序结构程序设计3.5.1顺序程序设计顺序程序完全按指令书写的前后顺序执行每一条指令,是最基本、最常见的程序结构计算移位代码转换例3.58data segmentX dw5Y dw6Z dw7W dw?data endscode segment

assumecs:code,ds:data

movax,X addax,Y addax,Z movW,ax

code ends end例3.59-(1)data segment

qvar dq1234567887654321hdata endscode segmentassumecs:code,ds:data moval,byteptrqvar[6] movbyteptrqvar[7],al moval,byteptrqvar[5] movbyteptrqvar[6],al moval,byteptrqvar[4] movbyteptrqvar[5],al moval,byteptrqvar[3] movbyteptrqvar[4],al图示例3.59-(2) moval,byteptrqvar[2] movbyteptrqvar[3],al moval,byteptrqvar[1] movbyteptrqvar[2],al moval,byteptrqvar[0] movbyteptrqvar[1],al movbyteptrqvar[0],0………12

34

56

78

87

65

43

21h34

56

78

87

65

43

21

00h移位后图示64位数据左移8位123456788765432100qvar[0]qvar[1]qvar[2]qvar[3]qvar[4]qvar[5]qvar[6]qvar[7]例题3.60代码转换-(1);查表法,实现一位16进制数转换为ASCII码显示data segment

ASCII db30h,31h,32h,33h,34h,35h db36h,37h,38h,39h ;0~9的ASCII码

db41h,42h,43h,44h,45h,46h ;A~F的ASCII码hex db0bh ;任意设定了一个待转换的一位16进制数data endscode segmentassumecs:code,ds:data例题3.60代码转换-(2)

movbx,offsetASCII ;BX指向ASCII码表 moval,hex ;AL取得一位16进制数,正是ASCII码表中位移 andal,0fh ;只有低4位是有效的,高4位清0

xlat

;换码:AL←DS:[BX+AL] movdl,al ;入口参数:DL←AL movah,2 ;02号DOS功能调用 int21h ;显示一个ASCII码字符

code ends

end3.5.2分支程序设计分支程序根据条件是真或假决定执行与否判断的条件是各种指令,如CMP、TEST等执行后形成的状态标志转移指令Jcc和JMP可以实现分支控制单分支:求绝对值等双分支多分支单分支程序设计条件成立跳转,否则顺序执行分支语句体;注意选择正确的条件转移指令和转移目标地址第3章例题求绝对值;计算AX的绝对值

cmpax,0

jnsnonneg ;分支条件:AX≥0

negax ;条件不满足,求补nonneg:

movresult,ax ;条件满足;计算AX的绝对值

cmpax,0

jlyesneg ;分支条件:AX<0 jmpnonnegyesneg:

negax ;条件不满足,求补nonneg: movresult,ax ;条件满足GoodBad例题无符号数除以2;将AX中存放的无符号数除以2,如果是奇数,则加1后除以2 testax,01h ;测试AX最低位

jzeven ;最低位为0:AX为偶数

addax,1 ;最低位为1:AX为奇数,需要加1even: rcrax,1 ;AX←AX÷2 ;如果采用SHR指令,则不能处理AX=FFFFH的特殊情况双分支程序设计条件成立跳转执行第2个分支语句体,否则顺序执行第1个分支语句体。注意第1个分支体后一定要有一个JMP指令跳到第2个分支体后第3章例题显示BX最高位(1) shlbx,1 ;BX最高位移入CF

jcone ;CF=1,即最高位为1,转移 movdl,’0’ ;CF=0,即最高位为0,DL←’0’

jmptwo

;一定要跳过另一个分支体one: movdl,’1’ ;DL←’1’two: movah,2 int21h ;显示对比双分支程序改为单分支程序例题显示BX最高位(2) ……….shlbx,1 ;BX最高位移入CF

jncone ;CF=0,即最高位为0,转移 movdl,’1’ ;CF=1,即最高位为1,DL←’1’

jmptwo

;一定要跳过另一个分支体one: movdl,’0’

;DL←’0’two: movah,2 int21h ;显示双分支程序改为单分支程序对比例题显示BX最高位(3) movdl,’0’ ;DL←’0’ shlbx,1 ;BX最高位移入CF

jnctwo ;CF=0,最高位为0,转移 movdl,’1’ ;CF=1,最高位为1,DL←’1’two: movah,2 int21h ;显示

……….编写分支程序,需留心分支的开始和结束判断有无实根-(1)……….moval,_bimulalmovbx,ax ;BX中为b2moval,_aimul_cmovcx,4imulcx

;AX中为4ac(DX无有效数据)判断有无实根-(2) cmpbx,ax ;比较二者大小

jgeyes

;条件满足? movtag,0 ;第一分支体:条件不满足,tag←0

jmpdone ;跳过第二个分支体yes: movtag,1 ;第二分支体:条件满足,tag←1done: ………. ;寄存器AL中是字母Y或y,则令AH=0;否则令AH=-1 cmpal,’Y’ ;AL是大写Y否?

jznext ;是,转移 cmpal,’y’ ;AL是小写y否?

jznext ;是,转移

movah,-1 ;不是Y或y,则AH=-1,结束

jmpdone

;一定要跳过另一个分支体next: movah,0 ;是Y或y,则AH=0,结束done: ...单分支和双分支多分支程序设计多个条件对应各自的分支语句体,哪个条件成立就转入相应分支体执行。多分支可以化解为双分支或单分支结构的组合,例如:orah,ah ;等效于cmpah,0jzfunction0 ;ah=0,转向function0decah ;等效于cmpah,1jzfunction1 ;ah=1,转向function1decah ;等效于cmpah,2jzfunction2 ;ah=2,转向function2第3章图示多分支结构AH=0fuction0YNAH=1fuction1YNAH=2fuction2YN地址表形成多分支需要在数据段事先安排一个按顺序排列的转移地址表输入的数字作为偏移量。因为只有2个字节16位偏移地址,所以偏移量需要乘2关键是要理解间接寻址方式JMP指令地址表分支1地址分支2地址...Table dbdisp1,disp2,disp3,disp4,...

msg db'Inputnumber(1~8):',0dh,0ah,'$'msg1 db'Chapter1:...',0dh,0ah,'$'msg2 db'Chapter2:...',0dh,0ah,'$‘ ...msg8 db'Chapter8:...',0dh,0ah,'$'table dwdisp1,disp2,disp3,disp4 dwdisp5,disp6,disp7,disp8 ;取得各个标号的偏移地址数据段-(1)此处等同于offsetdisp1start1: movdx,offsetmsg ;提示输入数字

movah,9 int21h movah,1 ;等待按键

int21h cmpal,'1' ;数字<1?

jbstart1 cmpal,'8' ;数字>8?

jastart1

andax,000fh ;将ASCII码转换成数字代码段-(2)

decax shlax,1 ;等效于addax,ax

movbx,ax

jmptable[bx];(段内)间接转移:IP←[table+bx]start2: movah,9 int21h

...disp1: movdx,offsetmsg1 ;处理程序1

jmpstart2 ...代码段-(3)可以改为calltable[bx]对应修改为ret3.5.3循环程序设计循环结构一般是根据某一条件判断为真或假来确定是否重复执行循环体循环指令和转移指令可以实现循环控制循环指令LOOPE转移指令多重循环循环指令LOOP循环结构

结束

初始化

循环的初始状态

循环体

循环的工作部分及修改部分

计数控制循环条件控制循环修改部分控制条件YNdata segmentsum dw?data endscode segmentassumecs:code,ds:data xorax,ax ;被加数AX清0 movcx,100again: addax,cx

;从100,99,...,2,1倒序累加

loopagain movsum,ax ;将累加和送入指定单元code ends end求和

计数控制循环循环次数固定;用二进制显示从键盘输入的一个字符的ASCII码

movah,1 ;从键盘输入一个字符

int21h

movbl,al ;BL←AL=字符的ASCII码;DOS功能会改变AL内容,故字符ASCII码存入BL

movah,2

movdl,':' ;显示一个分号,用于分隔

int21h显示从键盘输入的字符的ASCII码

-(1)

movcx,8 ;CX←8(循环次数)again: shlbl,1 ;左移进CF,从高位开始显示

movdl,0 ;MOV指令不改变CF

adcdl,30h ;DL←0+30H+CF;CF若是0,则DL←'0';若是1,则DL←'1'

movah,2

int21h ;显示

loopagain

;CX减1,如果CX未减至0,则循环

计数控制循环循环次数固定显示从键盘输入的字符的ASCII码

-(2)

movax,wordX ;测试目标送AX movcx,16

;循环计数器置初值 movdl,-1 ;计位器置初值again: incdl testax,1 rorax,1 ;循环指令不影响ZF

loopeagain

;CX≠0且ZF=1(测试位为0),继续循环

jenotfound movbyteY,dl

jmpdonenotfound: movbyteY,-1 ;ZF=1,16个位均为0done: ……例子

计数控制循环最大循环次数固定,满足条件退出

movbx,offsetstringagain: moval,[bx] ;取一个字符 oral,al ;是否为结尾符0

jzdone ;是,退出循环 cmpal,'A' ;是否为大写A~Z

jbnext cmpal,'Z'

janext oral,20h

;是,转换为小写字母(使D5=1) mov[bx],al ;仍保存在原位置next: incbx

jmpagain ;继续循环done: ………大小写

条件控制循环利用标志退出大小写字母仅D5位不同冒泡法“冒泡法”是一种排序算法,不是最优的算法,但它易于理解和实现冒泡法从第一个元素开始,依次对相邻的两个元素进行比较,使前一个元素不大于后一个元素;将所有元素比较完之后,最大的元素排到了最后;然后,除掉最后一个元素之外的元素依上述方法再进行比较,得到次大的元素排在后面;如此重复,直至完成就实现元素从小到大的排序这需要一个双重循环程序结构图示冒泡法的排序过程序号数比较遍数123413228531641558321615885161583285158163285815163285第3章

mov

cx,count ;CX←数组元素个数

deccx ;元素个数减1为外循环次数outlp: mov

dx,cx ;DX←内循环次数

movbx,offsetarrayinlp:

moval,[bx] ;取前一个元素

cmpal,[bx+1] ;与后一个元素比较

jnanext ;前一个不大于后一个元素,则不进行交换

xchgal,[bx+1] ;否则,进行交换

mov[bx],alnext: incbx ;下一对元素

decdx

jnzinlp ;内循环尾

loopoutlp ;外循环尾计数控制双重循环;现有一个以$结尾的字符串,要求剔除其中的空格

…….string db’Letushaveatry!’,’$’ …….. movsi,offsetstringmovdi,offsetstringoutlp: cmpbyteptr[di],’$’

;外循环,先判断后循环 jzdone ;为$结束 cmpbyteptr[si],’’

;检测是否是空格 jnznext ;不是空格继续循环剔除空格-(1) movdi,si ;是空格,进入剔除空格分支 ;该分支是循环程序段inlp: incdi moval,[di] ;前移一个位置 mov[di-1],al

cmpbyteptr[di],’$’

;内循环,先循环后判断 jnzinlp

jmpoutlpnext: incsi ;继续对后续字符进行处理

jmpoutlpdone: ……… ;结束剔除空格-(2)条件控制双重循环3.5.4子程序设计把功能相对独立的程序段单独编写和调试,作为一个相对独立的模块供程序使用,就形成子程序子程序可以实现源程序的模块化,可简化源程序结构,可以提高编程效率子程序设计要利用过程定义伪指令参数传递是子程序设计的重点和难点子程序可以嵌套;一定条件下,还可以递归和重入程序定义伪指令过程名 proc[near|far] ...过程名 endp过程名(子程序名)为符合语法的标识符NEAR属性(段内近调用)的过程只能被相同代码段的其他程序调用FAR属性(段间远调用)的过程可以被相同或不同代码段的程序调用对简化段定义格式,在微型、小型和紧凑存储模式下,过程的缺省属性为near;在中型、大型和巨型存储模式下,过程的缺省属性为far对完整段定义格式,过程的缺省属性为near用户可以在过程定义时用near或far改变缺省属性子程序的常见格式subname proc ;具有缺省属性的subname过程 pushax ;保护寄存器:顺序压入堆栈 pushbx ;ax/bx/cx仅是示例 pushcx … ;过程体 popcx ;恢复寄存器:逆序弹出堆栈 popbx popax

ret ;过程返回subname endp ;过程结束第3章;子程序功能:实现光标回车换行dpcrlf proc

;过程开始

pushax

;保护寄存器AX和DX

pushdx movdl,0dh

;显示回车 movah,2 int21h movdl,0ah

;显示换行 movah,2 int21h

popdx

;恢复寄存器DX和AX popax ret

;子程序返回dpcrlf endp

;过程结束例题无参数传递的子程序ALdisp proc

;实现al内容的显示

pushax

;过程中使用了AX、CX和DX

pushcx pushdx

pushax

;暂存ax movdl,al ;转换al的高4位 movcl,4 shrdl,cl ordl,30h ;al高4位变成3 cmpdl,39h jbealdisp1 adddl,7 ;是0Ah~0Fh,还要加上7aldisp1: movah,2 ;显示 int21h子程序-(1)

popdx

;恢复原ax值到dx anddl,0fh ;转换al的低4位 ordl,30h cmpdl,39h jbealdisp2 adddl,7aldisp2: movah,2 ;显示 int21h

popdx popcx popax ret

;过程返回ALdisp endp子程序-(2)

... ;主程序,同例4.8源程序 movbx,offsetarray;调用程序段开始 movcx,countdisplp: moval,[bx]

callALdisp

;调用显示过程 movdl,',' ;显示一个逗号,分隔数据 movah,2 int21h incbx loopdisplp ;调用程序段结束 ..... ;过程定义 end主程序-(3)HTOASC proc;将AL低4位表达的一位16进制数转换为ASCII码 andal,0fh cmpal,9 jbehtoasc1 addal,37h ;是0AH~0FH,加37H

ret

;子程序返回htoasc1: addal,30h ;是0~9,加30H

ret

;子程序返回HTOASC endp例题具有多个出口的子程序3.5.4.2子程序的参数传递入口参数(输入参数):主程序提供给子程序出口参数(输出参数):子程序返回给主程序参数的形式:①数据本身(传值)②数据的地址(传址)传递的方法:①寄存器②变量③堆栈求校验和子程序计算数组元素的“校验和”校验和是指不记进位的累加入口参数: 数组的逻辑地址(传址) 元素个数(传值)出口参数: 求和结果(传值)把参数存于约定的寄存器中,可以传值,也可以传址。子程序对带有出口参数的寄存器不能保护和恢复(主程序视具体情况进行保护)子程序对带有入口参数的寄存器可以保护,也可以不保护;但最好一致例子A入口参数:CX=元素个数,DS:BX=数组的段地址:偏移地址出口参数:AL=校验和用寄存器传递参数

……… ;设置入口参数(含有DS←数组的段地址) movbx,offsetarray

;BX←数组的偏移地址 movcx,count ;CX←数组的元素个数

callchecksuma

;调用求和过程 movresult,al ;处理出口参数 ……例子A-主程序checksuma proc xoral,al ;累加器清0suma: addal,[bx]

;求和 incbx ;指向下一个字节

loopsuma retchecksuma endp end例子A-子程序主程序和子程序直接采用同一个变量名共享同一个变量,实现参数的传递不通模块间共享时,需要声明例子B入口参数:count=元素个数,array=数组名(含段地址:偏移地址)出口参数:result=校验和用变量传递参数

;主程序

callchecksumb ;子程序checksumb proc pushax pushbx pushcx xoral,al ;累加器清0 movbx,offsetarray

;BX←数组的偏移地址 movcx,count

;CX←数组的元素个数例子B-(1)sumb: addal,[bx] ;求和 incbx loopsumb movresult,al ;保存校验和 popcx popbx popax retchecksumb endp例子B-(2)主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数子程序将出口参数压入堆栈,主程序弹出堆栈取得它们例子C入口参数:顺序压入偏移地址和元素个数出口参数:AL=校验和用堆栈传递参数

……. movax,offsetarray

pushax movax,count

pushax

callchecksumc

addsp,4 movresult,al ………例子C-主程序图示要注意堆栈的分配情况,保证参数存取正确、子程序正确返回,并保持堆栈平衡checksumc proc

pushbp movbp,sp

;利用BP间接寻址存取参数 pushbx pushcx

movbx,[bp+6]

;SS:[BP+6]指向偏移地址

movcx,[bp+4]

;SS:[BP+6]指向元素个数 xoral,alsumc: addal,[bx] incbx loopsumc popcx popbx

popbp retchecksumc endp例子C-子程序图示堆栈区及参数主程序实现平衡堆栈:addsp,n子程序实现平衡堆栈:retn子程序的嵌套子程序内包含有子程序的调用就是子程序嵌套没有什么特殊要求ALdisp proc

pushax

pushcx ;实现al内容的显示

pushax

;暂存ax

movcl,4 shral,cl

;转换al的高4位

callhtoasc

;子程序调用(嵌套)

popax

;转换al的低4位

callhtoasc

;子程序调用(嵌套) popcx popax retALdisp endp嵌套子程序-(1);将AL低

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论