DOS环境程序设计_第1页
DOS环境程序设计_第2页
DOS环境程序设计_第3页
DOS环境程序设计_第4页
DOS环境程序设计_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

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

文档简介

第8章DOS环境程序设计熟悉DOS应用程序特点和DOS功能调用熟悉串操作指令掌握输入输出指令及应用理解初始化编程、中断机制和编程28.1DOS编程DOS环境是一个简单的16位操作系统平台设计运行于8086和8088处理器也可运行于IA-32处理器的实地址工作方式DOS的特点DOS是单用户单任务操作系统DOS系统只有一个特权级别程序可以访问任意资源Windows操作系统模拟有一个MS-DOS环境基于Windows保护方式的一个8086仿真环境3DOS编程的注意事项16位DOS环境默认采用16位操作数尺寸主要使用16位或8位寄存器、操作数和寻址方式堆栈以16位为单位压入PUSH和弹出POP数据IA-32处理器的实地址工作方式还允许使用32位寄存器、操作数和寻址方式大多数新增的32位通用指令特别注意:偏移地址只有16位48.1.1实地址存储模型主存空间1MB(=220B):00000H~FFFFFH程序设计时分段管理,但有两个限制:每个段最大为64KB段只能开始于低4位地址全为0的物理地址处逻辑地址=段地址∶偏移地址16位段寄存器保存20位段起始地址的高16位偏移地址也用16位数据表示物理地址=段地址×16+偏移地址左移二进制4位(十六进制1位)示意图5实地址存储模型的逻辑地址和物理地址返回616位存储器寻址方式16位有效地址=基址寄存器+变址寄存器+位移量基址寄存器:BX、BP变址寄存器:SI、DI位移量:8或16位有符号值多种主存寻址方式直接寻址

MOVAX,WVAR寄存器间接寻址

MOVAX,[BX]寄存器相对寻址

MOVAX,[BP+4]基址变址寻址

MOVAX,[BX+SI]相对基址变址寻址

MOVAX,[BX+DI-2]7DOS地址空间分配88.1.2DOS应用程序框架;eg0800.asminDOS includeio16.inc ;包含32位输入输出文件

.data ;定义数据段

…… ;数据定义(数据待填)

.code ;定义代码段start: ;程序执行起始位置

movax,@data movds,ax

…… ;主程序(指令待填)

exit0 ;程序正常执行结束

…… ;子程序(指令待填)

endstart ;汇编结束9〔例8-1〕DOS应用程序

includeio16.inc ;包含16位输入输出文件

.data ;数据段msg byte'Hello,Assembly!',13,10,0 ;定义要显示的字符串

.code ;代码段start: ;程序起始位置

movax,@data movds,ax

moveax,offsetmsg ;指定字符串的偏移地址

calldispmsg ;调用I/O子程序显示信息

exit0 ;程序正常执行结束

endstart ;汇编结束示意图10DOS应用程序的开发过程返回DOS16.BAT进入DOS环境MAKE16.BAT汇编连接118.1.3DOS功能调用DOS操作系统的系统函数(功能)以中断服务程序形式提供,采用软件中断进行功能调用,使用寄存器传递参数基本输入输出系统ROM-BIOS、操作系统DOS和Linux都采用中断调用方式提供系统功能DOS系统调用一般有如下4个步骤:(1)在AH寄存器中设置系统功能调用号(2)在指定寄存器中设置入口参数(3)用中断调用指令(INTN)执行功能调用(4)根据出口参数分析功能调用执行情况12DOS基本功能调用(INT21H)子功能号功能参数AH=01H输入一个字符AL=输入字符的ASCII码AH=02H输出一个字符DL=字符的ASCII码AH=09H输出一个字符串DX=字符串地址AH=4CH程序执行结束AL=返回代码13〔例8-2〕DOS功能调用程序

.modelsmall .686 .stack

.data ;数据段msg byte'Hello,Assembly!',13,10,'$' ;显示的字符串

.code ;代码段start: movax,@data movds,ax

movah,9

movdx,offsetmsg ;指定字符串的偏移地址

int21h ;DOS功能调用显示信息

movax,4c00h ;执行结束

int21h endstart ;汇编结束14字符显示dispmsg proc pusheax

pushebx pushedx movebx,eaxdispm1: moval,[ebx]

testal,al

jzdispm2

movah,2

movdl,al

int21h

incebx jmpdispm1dispm2: popedx

popebx popeax retdispmsg endp15字符输入readmsg proc pushebx pushecx movebx,eax movecx,eaxrdm1:

movah,1 int21h

cmpal,0dh jzrdm2 mov[ebx],al incebx jmprdm1rdm2: movbyteptr[ebx],0 cmpebx,ecx jzrdm1 subebx,ecx moveax,ebx popecx popebx retreadmsg endp168.2

串操作类指令数据串(数组):以字节、字和双字为单位的多个数据存放在连续的主存区域中源操作数:允许段超越:DS:[ESI]目的操作数:不允许段超越:ES:[EDI]每执行一次串操作:ESI和EDI自动±1/2/4以字节为单位(用B结尾)操作:地址指针±1以字为单位(用W结尾)操作:地址指针±2以双字为单位(用D结尾)操作:地址指针±4DF=0(执行CLD指令):地址指针增加(+)DF=1(执行STD指令):地址指针减小(-)178.2.1

串传送指令 MOVSB|MOVSW|MOVSD;串传送:ES:[EDI]←DS:[ESI];然后:ESI←ESI±1/2/4,EDI←EDI±1/2/4

STOSB|STOSW|STOSD;串存储:ES:[EDI]←AL/AX/EAX;然后:EDI←EDI±1/2/4

LODSB|LODSW|LODSD;串读取:AL/AX/EAX←DS:[ESI];然后:ESI←ESI±1/2/4

REP;执行一次串指令,ECX减1;直到ECX=018〔例8-3〕字符串复制程序-1

.modelsmall .686 .stack .datasrcmsg

byte'Tryyourbest,whynot.','$'

dstmsg byte

sizeof

srcmsgdup(?) .codestart: movax,@data

movds,ax ;设置数据段DS

moves,ax ;设置附加段ES=DS19〔例8-3〕字符串复制程序-2

mov

esi,offset

srcmsg

;ESI=源字符串地址

mov

edi,offset

dstmsg

;ESI=源字符串地址

mov

ecx,lengthof

srcmsg

;ECX=字符串长度

cld

;地址增量传送

repmovsb

;重复字符串传送

movah,9 ;显示字符串

mov

edx,offset

dstmsg

int21h

endstartagain:movsb loopagainagain:mov

al,[esi]

mov[edi],al

addesi,1

addedi,1

loopagain20〔例8-4〕直接清除屏幕程序

.modelsmall .codestart: movdx,0b800h moves,dx movdi,0 ;设置ES:DI=B800H∶0000H

movcx,25*80 ;设置CX=填充个数

movax,0720h ;设置AX=填充内容

cld repstosw

movax,4c00h int21h endstart218.2.2

串检测指令

CMPSB|CMPSW|CMPSD;串比较:DS:[ESI]-ES:[EDI];然后:ESI←ESI±1/2/4,EDI←EDI±1/2/4

SCASB|SCASW|SCASD;串扫描:AL/AX/EAX-ES:[EDI];然后:EDI←EDI±1/2/4

REPE|REPZ;执行一次串指令,ECX减1;直到ECX=0或ZF=0

REPNE|REPNZ;执行一次串指令,ECX减1;直到ECX=0或ZF=122〔例8-5〕等长字符串比较程序

moves,ax

mov

ecx,count

mov

esi,offsetstring1

mov

edi,offsetstring2

cld

repz

cmpsb

;重复比较,不同或比较完

jnefound

;发现不同字符,转移

mov

al,'Y'

;字符串相同,显示Y

jmpdonefound: mov

al,'N' ;字符串不同,显示Ndone:23〔例8-6〕字符串查找程序-1 movedx,0 moves,dx movedi,edx ;逻辑地址(ES:[EDI]=0:0)起始

movecx,8000h ;32KB主存空间

cldagain1: movedx,sizeofsearch;EDX=待查找字符串长度

movesi,offsetsearch;ESI=待查找字符串地址

lodsb

;取出第一个待比较的字符AL=DS;[ESI],ESI=ESI+1

repnzscasb

;重复扫描:AL-ES:[EDI],EDI=EDI+1 jecxznext ;ECX=0,扫描到最后字符,转移24〔例8-6〕字符串查找程序-2

movebx,edi

;不是最后,保存第一个字符相同时的地址again2: decedx jzfound ;比较完所有字符,查找到

lodsb

;比较下一个字符

scasb jzagain2 ;还相同,继续比较

movedi,ebx

;不是完全相同,恢复第一个字符相同时的地址

jmpagain1 ;重新从第一个字符开始比较25〔例8-6〕字符串查找程序-3next: jnznofound

;最后一个字符不相同,没有查找到

decedx jzfound

;待查找内容只有一个字符,查找到nofound: movdl,'N' ;未查找到,显示N jmpdonefound: movdl,'Y' ;查找到,显示Y268.3输入输出程序设计外部设备通过输入输出接口电路(I/O接口)与主机相连,对外设编程实际上是针对I/O接口电路编程I/O接口电路呈现给程序员的则是各种可编程寄存器数据寄存器状态寄存器控制寄存器I/O接口寄存器使用编号区别

输入输出地址=I/O地址=I/O端口(Port)汇编语言程序员使用I/O指令通过I/O地址访问外设278.3.1

输入输出指令输入指令IN:数据从I/O接口输入到微处理器

INAL/AX/EAX,i8/DX输出指令OUT:数据从微处理器输出I/O接口

OUTi8/DX,AL/AX/EAX串输入INS指令串输出OUTS指令INAL,21HINAL,DX举例OUT

21H,ALOUTDX,AL举例输出:明确向哪个端口输出什么数据输入:清楚从哪个端口输入什么数据281.I/O寻址方式直接寻址I/O指令直接提供8位I/O地址只能寻址最低256个I/O地址(00~FFH)用i8表示I/O地址,表达形式上与立即数一样DX间接寻址用DX寄存器保存访问的I/O地址可寻址全部I/O地址(0000~FFFFH)直接书写成DX,表示I/O地址64K个I/O地址,不分段292.I/O数据传输量8位I/O传输:I/O指令使用AL16位I/O传输:I/O指令使用AX32位I/O传输:I/O指令使用EAXout

20h,alout20h,axout

20h,eaxmovdx,3fchout

dx,alout

dx,axout

dx,eax举例in

al,20hinax,20hineax,

20hmovdx,3fchin

al,dxin

ax,dxin

eax,dx举例30〔例8-7〕读取CMOSRAM数据程序-1 includeio16.inc .codestart: moval,9 ;AL=9(准备从9号单元获取年代数据)

out70h,al ;从70H的I/O地址输出,选择CMOSRAM的9号单元

inal,71h ;从71H的I/O地址输入,获取9号单元的内容

calldisphb

;显示AL内容,即年代

moval,'-'

;显示分隔符“-”

calldispc〔例8-7〕读取CMOSRAM数据程序-2

moval,8

;AL=8(从8号单元获取月份数据)

out70h,al inal,71h

calldisphb

;显示月份

moval,'-'

;显示分隔符“-”

calldispc

moval,7

;AL=7(从7号单元获取日期数据)

out70h,al inal,71h

calldisphb

;显示日期21-Nov-23显示结果8.3.2

定时器初始化编程定时控制在计算机系统中具有重要作用初始化编程:通过向接口电路写入命令字或控制字,选择其工作方式、设置原始工作状态等驱动程序:操纵I/O接口完成具体工作的程序最底层的驱动程序实现基本数据传输、操作控制等功能操作系统提供更加便于使用的程序模块或函数应用程序为最终用户呈现操作界面使用8253或其兼容电路构成定时控制接口有3个独立的16位计数器电路(通道)每个计数器电路支持6种工作方式处理器必须对其初始化编程331.写入方式控制字控制字写入控制字I/O地址:43H(PC机)计数器读写格式工作方式数制D7D6D5D4D3D2D1D000计数器001计数器110计数器211非法(8253)11读回命令(8254)00计数器锁存命令01只读写低字节10只读写高字节11先读写低字节后读写高字节000方式0001方式1*10方式2*11方式3100方式4101方式50二进制1十进制34方式控制字编程示例

;假设:8253控制端口地址:43H ;设置其中计数器0为方式0 ;采用二进制计数,先低后高写入计数值

moval,30h

;方式控制字:30H=00110000B

out43h,al

;写入控制端口:43H352.写入计数值选择二进制时计数值范围:0000H~FFFFH0000H是最大值,代表65536选择十进制(BCD码)计数值范围:0000~99990000代表最大值10000计数值写入计数器各自的I/O地址PC机上,计数器0、1和2的I/O地址依次是40H、41H和42H按方式控制字规定的读写格式进行36计数值编程示例

;假设:8253的计数器0、1、2端口地址:40H~42H ;设置计数器0采用二进制计数 ;写入计数初值:1024(=400H)

movax,1024

;计数初值:1024(=400H)

;写入计数器0地址:40H

out40h,al ;写入低字节计数初值

mov

al,ah out40h,al ;写入高字节计数初值373.扬声器频率控制;发音频率设置子程序;入口参数:AX=1.19318×106÷发音频率speaker proc pushax

;暂存入口参数

moval,0b6h

;定时器2为方式3,先低后高

out43h,al ;写入方式控制字

popax

;恢复入口参数

out42h,al ;写入低8位计数值

mov

al,ah out42h,al ;写入高8位计数值

retspeaker endp定时器的控制端口地址:43H读写计数器2计数值端口地址:42H388.3.3

扬声器控制编程39〔例8-8〕控制扬声器程序 ;数据段freq word

1989

;600Hz频率对应的计数值:1193180/600≈1989

;代码段,主程序

mov

ax,freq callspeaker ;设置扬声器的音调

callspeakon ;打开扬声器声音

movah,1

;等待按键 int21h

callspeakoff ;关闭扬声器声音40扬声器发音控制speakon proc ;扬声器开子程序

pushax

inal,61h ;读取61H端口的原控制信息

oral,03h ;D1D0=PB1PB0=11,其他不变

out61h,al

;直接控制发声

popax retspeakon

endp;扬声器关子程序andal,0fch;D1D0=PB1PB0=00,其他不变418.4

中断控制编程中断是计算机系统中非常重要的一种技术利用外部中断可以实时响应外部设备的数据传送请求能够及时处理外部意外或紧急事件利用内部中断提供发现、调试并解决程序执行时异常情况的有效途径428.4.1中断控制系统IA-32处理器能够处理256个中断用中断向量号0~255区别除法错异常(向量号0)调试异常(向量号1)非屏蔽中断(向量号2)断点异常(向量号3)溢出异常(向量号4)无效代码异常(向量号6)通用保护异常(向量号13)页面失效异常(向量号14)……43除法错中断执行除法指令时,若除数为0或商超过了寄存器所能表达的范围,产生的一个向量号为0的内部中断〔例8-9〕产生除法错中断的程序

;数据段msg byte0dh,0ah,'Nodivideoverflow!',0

;代码段

callreaduiw

movbl,1

divbl

mov

eax,offset

msg;没有除法错,显示信息

calldispmsg示意图44除法错中断的运行示例返回45溢出中断执行溢出中断指令INTO时,若溢出标志OF为1,产生的一个向量号4的内部中断〔例8-10〕产生溢出中断的程序

callreaduib

addal,100

jno

noflow

;没有溢出,转移

into

;有溢出,产生溢出中断

jmpdonenoflow: mov

eax,offset

msg

;显示无溢出信息

calldispmsgdone:46中断指令

INTi8 ;中断调用指令:调用i8号中断服务程序

IRET ;中断返回指令:从服务程序返回主程序

INTO ;溢出中断指令:OF=1,产生4号中断

STI ;开中断指令:允许响应可屏蔽中断请求

CLI ;关中断指令:禁止响应可屏蔽中断请求47中断向量表中断服务程序可存于主存任何位置通过地址表结构将中断向量号转为地址表项,进而获得中断服务程序的入口地址实地址方式下,称之为中断向量表物理地址00000H,对应向量号从0开始依次每4个字节安排一个中断向量含有16位段地址和16位偏移地址的逻辑地址低字部分是偏移地址、高字部分是段地址256个中断占用1KB区域示意图48实方式的中断向量表结构返回498.4.2

内部中断服务程序编写内部中断服务程序与编写子程序类似利用过程定义伪指令PROC/ENDP第1条指令通常为开中断指令STI最后用中断返回指令IRET通常采用寄存器传递参数主程序需要调用中断服务程序调用前,需要设置中断向量表对应项利用INTn指令调用中断服务程序50〔例8-11〕内部中断服务程序-1

.modelsmall .stack .dataintoff word?

;用于保存原中断服务程序的偏移地址intseg word?

;用于保存原中断服务程序的段基地址intmsg byte'AInstructionInterrupt!',0dh,0ah,0

;字符串(以0结尾)

.codestart: movax,@data movds,ax51〔例8-11〕内部中断服务程序-2 ;获取系统的原80H中断服务程序地址

movbx,0 moves,bx ;设置附加段ES=0,指向物理地址低端

movbx,80h ;BL=AL=N=80H

shlbx,1 shlbx,1 ;BX=N×4

movax,es:[bx] ;获取中断服务程序的偏移地址

movintoff,ax

movax,es:[bx+2] ;获取中断服务程序的段基地址

movintseg,ax52〔例8-11〕内部中断服务程序-3 ;设置本程序的80H中断服务程序地址

movax,offsetnew80h

moves:[bx],ax ;设置偏移地址

movax,segnew80h

moves:[bx+2],ax ;设置段基地址 ;中断调用

movdx,offsetintmsg ;设置入口参数DS和DX

int80h ;调用80H中断服务程序,显示字符串53〔例8-11〕内部中断服务程序-4 ;恢复系统的原80H中断服务程序地址

movax,intoff

moves:[bx],ax ;恢复偏移地址

movax,intseg

moves:[bx+2],ax ;恢复段基地址

movax,4c00h int21hAInstructionInterrupt!显示结果54〔例8-11〕内部中断服务程序-5new80h proc

;过程定义

sti

;开中断

pushax

;保护寄存器

pushbx pushsi

mov

si,dxnew1: mov

al,[si]

;获取欲显示字符

cmpal,0

;为“0”结束

jznew2

movbx,0

;ROM-BIOS调用显示一个字符

movah,0eh

int10h incsi

jmpnew1功能编号AH=0EHINT10H入口参数AL=ASCII字符,BX=0功能说明显示字符55〔例8-11〕内部中断服务程序-6new2: popsi

;恢复寄存器

popbx popax

iret

;中断返回new80h endp

;中断服务程序结束

;80H内部中断服务程序

;显示字符串(以0结尾)

;DS∶DX=缓冲区首地址AInstructionInterrupt!显示结果568.4.3

驻留中断服务程序没有驻留的程序执行结束后,使用的主存空间被DOS回收用于其他程序驻留TSR程序:程序执行结束保存在主存中断服务程序要让其他程序使用必须

温馨提示

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

评论

0/150

提交评论