汇编语言程序设计课件_第1页
汇编语言程序设计课件_第2页
汇编语言程序设计课件_第3页
汇编语言程序设计课件_第4页
汇编语言程序设计课件_第5页
已阅读5页,还剩189页未读 继续免费阅读

下载本文档

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

文档简介

第五章

汇编语言程序设计第五章

汇编语言程序设计程序是计算机命令(语句)的有序集合。

机器语言、汇编语言、高级语言机器语言是一种用二进制数表示指令和数据,能被机器直接识别的语言。

汇编语言弥补了机器语言的不足,采用助记符编程。但也是面对机器的,要求程序员对机器指令系统、内存空间分配了如指掌,地址是汇编语言关键所在,执行速度快,但可移植性差。高级语言是面向过程的,程序员没必要了解内存分配,更符合人的思维方式,执行速度相对慢一些,可移植性好。程序是计算机命令(语句)的有序集合。§5.1汇编语言的基本语法汇编语言源程序中的语句可以分为三种类型:指令语句,伪指令语句和宏指令语句。(1)指令语句:它是能产生目标代码,CPU可以执行的能完成特定功能的语句。(2)伪指令语句:它是一种不产生目标代码的语句,它仅仅在汇编过程中告诉汇编程序应如何汇编。伪指令语句是汇编程序在汇编时使用的。(3)宏指令语句:它是一种编程者利用伪指令语句自己定义的语句。§5.1汇编语言的基本语法汇编语言源程序中的语句1.伪指令的语句格式

1)标号标号名字段,它是任选字段。目标名后面不能用冒号“:”,标号名可以是常量名、变量名、过程名、结构名、记录名等。可以作为指令语句和伪指令语句的操作数,这时,标号名表示一个常量或存储器地址。1.伪指令的语句格式1)标号2)伪指令助记符或伪操作字段,不可省略。伪指令种类很多,如定义数据伪指令DB,DW,DD;段定义伪指令SEGMENT;定义过程伪指令PROC;…。它们是伪指令语句要求汇编程序完成的具体操作命令3)操作数本字段是否需要,需要几个,需要什么样的操作数等都由伪指令字段中伪指令来确定。操作数可以是一个常数(二进制、十进制、十六进制等)、字符串、常量名、变量名、标号、一些专用的符号(如BYTE,FAR,PARA等)。2)伪指令3)操作数4)注释任选字段,它必须以分号为开始,它的作用与指令语句的注释字段相同。2.常数、变量和标号常数、变量和标号是汇编语言能识别的数据项,它是指令和伪指令语句中操作数的基本组成部分。一个数据项包含有它的数值和属性两部分,这两部分对一条语句汇编成机器目标代码都有直接关系。4)注释2.常数、变量和标号常数、变1)常数常数是没有任何属性的纯数值。在汇编期间,它的值已能完全确定,且在程序运行中,它也不会发生变化。2)变量变量是代表存放在某些存储单元的数据,这些数据在程序运行期间随时可以修改。为了便于对变量的访问,它常常以变量名的形式出现在程序中,它可以认为是存放数据存储单元的符号地址。1)常数2)变量(1)变量的定义与预置:定义变量就是给变量分配存储单元,且对这个存储单元赋予一个符号名——变量名,同时将这些存储单元预置初值。定义变量是用数据定义伪指令DB,DW,DD等。例如:VAR_DATA SEGMENTDATA1DB 12HDATA2DB 34HDATA3DW 5678HVAR_DATA ENDS(1)变量的定义与预置:定义变量就是给变量分配存储单元,(2)数据定义伪指令:为数据项分配存储单元并预置初值。变量名表达式1,表达式2,…①数值表达式。DA_BYTE DB50H,50

DA_WORD DW 0A3F1H,4981H

(2)数据定义伪指令:为数据项分配存储单元并预置初值。变量名②?表达式:不带引号的?表示可预置任何内容。DA_B DB ?,?DA_W DW ?,?③字符串表达式:对于DB伪指令,为字符串中每一个字符分配一个字节单元。字符串必须是用引号括起来且不超过255个字符。字符串自左至右以字符的ASCII码按地址递增的排列顺序依次存放。STRING1DB 'ABCDEF'STRING2 DW 'AB','CD','EF'STRING3 DD'AB','CD'②?表达式:不带引号的?表示可预置任何内容。DA_B DB第五章汇编语言程序设计课件④带DUP表达式:DUP是定义重复数据操作符。变量名表达式1,DUP(表达式2)D_B1DB20H DUP(?)D_B2DB10HDUP('ABCD')D_W1DW10HDUP(4)④带DUP表达式:DUP是定义重复数据操作符。变量名表达3)标号标号是一条指令目标代码的符号地址,它常作为转移指令(含子程序调用指令)的操作数。LOP1: … …

LOOP LOP1 … JNE NEXT …NEXT: …(1)段属性(2)偏移量属性:(3)距离属性:①NEAR(近);②FAR(远)3)标号LOP1: …(1)段属性(1)SEG

格式:SEG <符号名>

功能是求符号名所在段的段基址。(2)OFFSET

格式:OFFSET <符号名>

功能是求符号名所在段的偏移地址。(3)TYPE

格式:TYPE<符号名>功能是获得符号名类型值。3.运算符(1)SEG 3.运算符(4)SIZE

格式:SIZE <符号名>功能是获得为符号名分配的字节数。为符号名定义的数据项必须是用重复格式DUP()定义的。(5)PTR

格式:<类型>PTR<符号名>功能是定义符号名为新类型。如,设内存变量D1是字节属性,把它的两个字节内容送到AX中MOVAX,WORDPTRD1(4)SIZEMOVAX,WORDPTRD1§5.2伪指令伪指令没有对应的机器指令,它不是由86系列CPU来执行,而是由MASM-86识别,并完成相应的功能。它在很大程度上规定了MASM-86的性能,因此也可称之为汇编命令。1.符号定义伪指令(赋值语句)1)EQU格式:<名字>EQU<表达式>2)=格式:<名字>=<表达式>§5.2伪指令伪指令没有对应的机器指令,它2.内存数据定义伪指令1)字节定义伪指令DB格式:[名字]DB<表达式或数据项表>3)4字节定义伪指令DD格式:[名字]DD<表达式或数据项表>2)字定义伪指令DW格式:[名字]DW<表达式或数据项表>2.内存数据定义伪指令1)字节定义伪指令DB3)4字3.段定义伪指令1).SEGMENT/ENDS格式:<段名> SEGMENT [定位方式][连接方式][‘类型名’] … <段名> ENDS段定义伪指令为程序的汇编和连接说明了段名、段的各种属性以及段的开始和结束。段名是自定义符,开始的段名与结束的段名必须相同。段的长度不超过64KB。3.段定义伪指令1).SEGMENT/END(1)定位方式(定位类型Align):定位方式指定段的起始地址边界,方式有4种。PAGE——指定起始地址的低8位是0,即其值能被256整除(称为页对齐)。PARA——指定起始地址的低4位是0,即其值能被16整除(称为段对齐)。这是系统隐含定位方式。WORD——指定起始地址的最低位是0,即其值能被2整除(称为字对齐)。BYTE——指定起始地址是任意值(称为字节对齐)。(1)定位方式(定位类型Align):定位方式指定段的起始(2)连接方式(组合类型):连接方式告诉连接程序,本段与其他段可按某种方式连接,它有6种选择。PUBLIC——告诉连接程序本段与其他同名同类别的段连接起来,公用一个段的起始地址,形成一个物理段。STACK——表示本段是堆栈段,连接方式同PUBLIC,连接后的段起始地址在SS寄存器中。连接程序要求源程序至少要有一个堆栈段,否则提示错误,此时,系统取约定堆栈段值。

(2)连接方式(组合类型):连接方式告诉连接程序,本段与其他空缺(NONE)——表示本段不与任何段连接,这是系统隐含连接方式。COMMON——表示本段与同名同类型的段共用同一段起始地址,即同名同类段相重叠,段的长度是最长段的长度。MEMORY——表示本段在连接时定位在所有段之上,即高地址处。AT表达式——表示本段定位在表达式值指定的段地址处。

空缺(NONE)——表示本段不与任何段连接,这是系2).ASSUME格式:ASSUME段寄存器:段定义名1[,段寄存器:段定义名2,…]ASSUME伪指令告诉汇编程序,将某一个段寄存器设置为存放某一个逻辑段的段地址,即明确指出源程序中的逻辑段与物理段之间的关系。当汇编程序汇编一个逻辑段时,即可利用相应的段寄存器寻址该逻辑段中的指令或数据。在一个源程序中,ASSUME伪指令定义符应该放在可执行程序开始位置的前面。ASSUME伪指令只是通知汇编程序有关段寄存器与逻辑段的关系,并没有给段寄存器赋予实际的初值。用户需要通过指令给有关段寄存器赋值。2).ASSUME.STACK64.DATADATA1DB15HDATA2DB29HSUMDB?.CODE3.简化段定义“.CODE”、“.DATA”和“.STACK”来分别对应寄存器CS、DS和SS。例如以下代码片段:MAINPROCFARMOVAX,@DATAMOVDS,AX……

.STACK643.简化段定义例

STSEGSEGMENTDB64DUP(?)STSEGENDS4过程(子程序)定义伪指令格式: <过程名> PROC [NEAR](或[FAR]) … <过程名> ENDP定义过程是为实现子程序调用而设的。调用格式为:CALL<过程名>

过程起始名和终止名必须相同。STSEGSEGMENT4过程(子5模块定义与连接伪指令1)NAME格式: NAME 模块名该伪指令说明程序模块的开始,并指出模块名。模块名是自定义符,它不能是系统保留字,每次汇编只能出现一次。若该伪指令默认,则取TITLE语句中的页标题前6个字符;若没有TITLE语句,则取源程序文件名为模块名。2)END格式:END [启动标号或过程名]5模块定义与连接伪指令1)NAME2)END该伪指令告诉汇编程序源文件结束,对于END后的语句可以不予理会,并给出执行程序的入口位置。END伪指令将标号的段值和偏移地址分别提供给CS和IP寄存器。方括号中的标号是任选项。如果有多个模块连接在一起,则只有主模块的END语句使用标号。6.列表伪操作1)LIST汇编程序遇到伪操作.LIST时,禁止其后的源程序和目标代码在列表文件中输出,直到下一个.LIST为止。.LIST伪操作规定将后面的源程序和目标代码列表输出。这个伪操作相当于列表文件的默认状态。该伪指令告诉汇编程序源文件结束,对于END后的语句可以不予2)TITLE格式:TITLE标题名功能是指定列表文件每一页的标题名,标题名可以是不超过80个字符的字符串。当源程序中未用NAME伪操作时,由TITLE伪操作指定的标题名的前六个字符,同时作为汇编以后得到的目标程序的模块名。如:TITLEMainProgram3)PAGE伪操作命令用来在汇编程序中设置列表文件每页的长度(行数)和每行的宽度(列数)。页长可以是10~255行,默认值为50行;行宽为60~132字符,默认值为80字符。2)TITLE3)PAGE7.其他伪操作1)RADIX通常,汇编语言源程序中常数的默认基数为十进制数,伪操作命令.RADIX可以改变这个默认的基数,格式为:

.RADIX表达式2)定位伪指令ORG格式: ORG<表达式>该伪指令把以下语句定义的内存数据或程序,从表达式指定的起点(偏移地址)开始连续存放,直至遇到新的ORG指令。表达式的值是一个无符号数。它一般用于数据段或代码段中。7.其他伪操作1)RADIX2)定位伪指§5.3系统功能调用DOS(DiskOperationSystem)和BIOS(BasicInputandOutputSystem)为用户提供了两组系统服务程序。用户程序可以调用这些系统服务程序。但在调用时应注意:第一,不用CALL命令;第二,不用这些系统服务程序的名称,而采用软中断指令INTn;第三,用户程序也不必与这些服务程序的代码连接。§5.3系统功能调用DOS(DiskOperBIOS是微机的基本I/O系统。包括系统测试程序、初始化引导程序、一部分中断矢量装入程序及外部设备的服务程序。由于这些程序固化在ROM中,只要机器通电,用户便可以调用它们。

DOS是微机的操作系统,负责管理系统的所有资源,协调微机的操作,其中包括大量的可供用户调用的服务程序,完成设备的管理及磁盘文件的管理。BIOS是微机的基本I/O系统。包括系统测试程序第一个途径是普通用户从键盘输入命令,DOS的COMMAND.COM模块接收、识别、处理键入的命令。第二个途径是高级用户通过用户程序去调用DOS和BIOS中的服务程序,高级用户需要对操作系统有较深入的了解。1)用户与DOS的关系第一个途径是普通用户从键盘输入命令,DOS的COM2)用户程序控制微机硬件的方式2)用户程序控制微机硬件的方式2.DOS系统功能调用8086/8088指令系统中,每执行一条软中断指令INTn,就调用一个相应的中断服务程序。当n=5~1FH时,调用BIOS中的服务程序,当n=20~3FH时,调用DOS中的服务程序。其中,

INT21H是一个具有多种功能的服务程序,一般称之为DOS系统功能调用。

DOS中断的规定,输入入口参数,然后执行INT指令,最后分析出口参数。2.DOS系统功能调用8086/8088指令系统中INT21H具有80个子功能中断服务程序,子功能的编号称为功能号。INT21H功能大致可以分为四个方面,即设备管理、目录管理、文件管理和其他。

设备管理:键盘输入、显示器输出、打印机输出、串行设备输入/输出、初始化磁盘、选择当前磁盘、取剩余磁盘空间等。目录管理:查找目录项、查找文件、置/取文件属性、文件改名等。文件管理:打开、关闭、读/写、删除文件等,这是DOS提供给用户的最重要的系统功能调用。其他功能:终止程序、置/取中断矢量、分配内存、置/取日期及时间等。INT21H具有80个子功能中断服务程序功能调用的格式:⑴传送入口参数到指定寄存器中;⑵功能号送入AH寄存器;⑶INT21H

有的程序没有入口参数,则只需安排后两个语句,调用结束后,系统将出口参数送到指定寄存器中或从屏幕上显示出来。

1号DOS系统功能调用,使用格式如下所示:

MOVAH,1INT21H

1)键盘输入单字符功能调用的格式:1号DOS系统功能调用,使没有入口参数,执行时,系统等待键盘输入,待程序员按下任何一键,系统先检查是否Ctrl-Break键,如果是则退出,否则将该键字符的ASCII码置入AL寄存器中,并在屏幕上显示该字符。

0AH号系统功能调用,将键盘输入的字符串写入到内存缓冲区中,缓冲区第一字节能存放的字节数,第二字节留给系统填写实际键入的字符个数,第三个字节开始存放键入的字符串,最后键入回车(↙)键表示字符串结束。实际键入的字符数不足填满缓冲区时,则其余字节填“0”;实际键入的字符数超过缓冲区的容量,则超出的字符将被丢失,而且响铃,表示向程序员发出警告。2)键盘输入字符串没有入口参数,执行时,系统等待键盘输入,待程序员┇

BUF DB 20 DB ? DB 20,DUP(?)

MOV DX,OFFSETBUF MOV AH,0AH INT 21H;定义缓冲区;0AH号系统功能调用┇;定义缓冲区;0AH号系统

2号系统功能调用,使用格式如下所示:

MOV DL,’A’ MOV AH,2 INT 21H

执行2号系统功能调用时,将置入DL寄存器中的字符从屏幕上显示输出(或打印机打印输出)。3)输出单字符4)输出字符串

9号系统功能调用,其功能是将指定的内存缓冲区中的字符串从屏幕上显示输出来(或打印输出)。缓冲区中的字符串必须以“$”字符作为结束标志。

2号系统功能调用,使用格式如下所示:3)输出单字符4)

BUF DB‘goodbye$’

┇MOV DX,OFFSETBUFMOV AH,9INT 21H执行9号系统功能调用时,将内存缓冲区BUF中存放的字符串(以“$”字符为结束)送屏幕显示输出(或送打印机打印输出)。BUF DB‘goodbye$’执行9号系统功3.BIOS中断调用BIOS是固化在ROM中的一组I/O驱动程序,它为系统各主要部件提供设备级控制,还为汇编语言程序设计者提供了字符I/O操作。与DOS功能调用相比,BIOS有如下特点:(1)调用BIOS程序虽然比调用DOS程序要复杂一些,但运行速度快,功能更强;(2)DOS的中断功能只是在DOS的环境下适用,而BIOS功能调用不受任何操作系统的约束;(3)某些功能只有BIOS具有。3.BIOS中断调用§

5.4汇编器的功能及汇编过程汇编器的主要功能是将由汇编语言(助记符)编写的源程序翻译成用机器语言(二进制代码)编写的目标程序。§5.4汇编器的功能及汇编过程汇编器的主要功能是DATA SEGMENT …}存放数据项的数据段DATA ENDSEXTRA SEGMENT …}存放数据项的附加段EXTRA ENDSSTACK1 SEGMENT PARA STACK …}作堆栈用的堆栈段STACK1 ENDSCOSEG SEGMENT

DATA SEGMENTASSUME CS:COSEG,DS:DATAASSUME SS:STACK1,ES:EXTRASTARTPROCFARMOV AX,DATA MOV DS,AX…}存放指令序列COSEG ENDS END STARTASSUME CS:COSEG,DS:DATA

计算机执行程序“从头到尾”,逐条顺序执行,直到程序结束。1.简单程序(顺序程序)【例1】用数据运算指令,对两个16位数做加法运算。这两个数从地址10050H开始连续存放,低位在小地址一端,结果存放在这两个数之后。DATASEGMENTORG50HData1DW?Data2DW?Data3DW?DATAENDS计算机执行程序“从头到尾”,逐条顺序执行,直到程STACKSEGMENTSTA1DB100DUP(?)STACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKSTARTPROCFARPUSH DS XORAX,AXPUSH AX;返回DOSMOV AX,DATA MOVDS,AX;DS=1000H

STACKSEGMENTSTARTP MOV SI,50H;被加数指针SI=50H MOV DI,52H;加数指针DI=52H MOV BX,54H ;和的指针BX=54H CLC ;清CF XOR AX,AX ;清AX MOV AX,[SI] ;取一个字到AX ADC AX,[DI] ;AX←AX+[DI]+CF MOV [BX],AX ;存一个字到[BX] COSEG ENDSEND START MOV SI,50H;被加数指针SI=5【例2】将内存10050H单元的内容拆成两段,每段4位,并将它们分别存入内存10051H和10052H单元。即10050H单元中的低4位放入10051H的低4位,10050H单元中的高4位放入10052H的低4位,而10051H和10052H的高4位均为零。DATASEGMENTORG50HData1DB?Data2DB?Data3DB?DATAENDS【例2】将内存10050H单元的内容拆成两段,每段4STACKSEGMENTSTA1DB100DUP(?)STACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKSTARTPROCFARPUSH DS XORAX,AXPUSH AX;返回DOSMOV AX,DATA MOVDS,AX;DS=1000H

STACKSEGMENTSTARTPMOVSI,50H;需拆字节的指针SI=50HMOVAL,[SI];取一个字节到AL中ANDAL,0FH;把AL的前4位清0MOV [SI+1],AL;把得到的后4位放到10051H单元MOVAL,[SI];再取出需拆字节放到AL中MOVCL,4SHR AL,CL;逻辑右移四次,前4位补0MOV[SI+2],AL;放入10052H单元

COSEG ENDSEND STARTMOVSI,50H;需拆字节的指针

分支程序是利用条件转移指令,使程序执行到某一指令后,根据条件是否满足,来改变程序的执行次序。程序使计算机有了判断的功能。经常先用比较指令或数据操作及位检测指令改变标志寄存器各个标志位。然后用条件转移指令进行分支。【例1】求AX累加器和BX寄存器中两个无符号数之差的绝对值,结果放在内存2800H单元中。2.分支程序分支程序是利用条件转移指令,使程序执行到某一指令后.MODELSMALL.STACK64.DATA ORG2800H AbsDataDW?.CODEABSPRG PROCFARMOVAX,@DATAMOVDS,AX.MODELSMALLCLC ;清除CFMOVCX,AXSUBAX,BX;AX←AX-BX,影响CFJCLow;CF=1转AA去执行(即AX<BX时转移)MOVDI,2800H;结果指针DI=2800HMOV[DI],AX;结果送到2800H和2801H单元JMP Out;暂停Low:

SUBBX,CX;BX←BX-CXOut:MOVDI,AbsDataMOV[DI],BXABSPRGENDPENDCLC ;清【例2】编制程序,从外设71号端口中取一个数M,判断其值是否在10和20之间,即10≤M<20。如果M≥20H,则送0FFH给外设73H端口;如果M<10,则送00H给外设73H;如果10≤M<20,则送88H给外设73H。.MODELSMALL.STACK64.DATAPrtAdd1DB71HPrtAdd2DB73H

.CODEPRTPRGPROCFARMOVAX,@DATAMOVDS,AX【例2】编制程序,从外设71号端口中取一个数M,判INAL,PrtAdd1;(AL)←71H端口的字节CLC;CF=0CMPAL,10;将(AL)与10比较JC ValLow10;小于10转ValLow10CMPAL,20 ;将(AL)与20相比较JCVal10To20 ;10≤(AL)<20转Val10To20MOVBL,0FFH ;(BL)←0FFHJMPOutputValLow10:MOV BL,00 JMP OutputVal10To20:MOV BL,88HINAL,Prt3循环程序Output:MOVAL,BLOUTPrtAdd2,AL;将0FFH输出到73H端口PRTPRGENDPEND循环结构程序是强制CPU重复执行某一指令系列(程序段)的一种程序结构形式,凡是要重复执行的程序段都可以按循环结构设计。3循环程序Output:MOVAL,BL(1)初始化:它完成建立循环次数计数器,设定变量和存放数据的内存地址指针(常用间接寻址方式)的初值,装入暂存单元的初值等。(2)循环体:这是程序的处理部分。(3)循环控制:包括修改变量和修改指针,为下一次循环做准备,以及修改循环计数器(计数器减1),判断循环次数是否到达。到达循环次数则结束循环;否则继续循环(即转移回去,再执行一次循环体)。(4)结束处理:它主要用来分析和存放程序的结果。(1)初始化:它完成建立循环次数计数器,设定变量和存放数【例1】求两个多字节数之和。这两个数在10050H地址开始的内存单元中,连续存放,低位在小地址一端,结果放在这两个数之后。设这两个多字节数均为八个字节长。【例1】求两个多字节数之和。这两个数在10050H地

.MODELSMALL .STACK64 .DATA ORG50HLopDat1DB23H,56H,45H,63H,78H,66H,90H,42HLopDat2DB13H,44H,86H,80H,24H,64H,56H,60HDatSum DB8DUP(?).CODELOPPRG PROCFARMOVAX,@DATAMOVDS,AX .MODELSMALL MOVSI,LopDat1;第一个数指针(SI)=0050H MOVDI,LopDat2;第二个数指针(DI)=0058HMOVBX,DatSum;结果指针(BX)=0060H MOVCX,4 ;循环(CX)=4 CLC;清进位CF=0Add4Nums:MOVAX,[SI];(AX)←((SI)),取一个字

ADCAX,[DI];(AX)←(AX)+((DI))+CF MOV[BX],AX ;存一个字到((BX)) MOVSI,LopDat1PUSHF ;CF进栈保护ADD SI,2 ;修改第一个数的地址指针(SI)←(SI)+2ADD DI,2 ;修改第二个数的地址指针(DI)←(DI)+2ADD BX,2 ;修改结果指针(BX)←(BX)+2POPF ;修复标志寄存器LOOPAdd4Nums;(CX)←(CX)-1,若(CX)≠0转Add4NumsLOPPRGENDPEND【例2】设计一个软件延时程序,要求延时时间1ms。PUSHF ;CF进栈保护【例2】设计一个软件延时程序,要求PUSHF和POPF指令分别为14和12个时钟周期,LOOPBX指令为3.4个时钟周期,即此循环体需要用14+12+3.4=29.4拍.MODELSMALL.STACK64.CODEPUSHF和POPF指令分别为14和12个时钟PRG 1MS PROCFARMOVAX,@DATAMOVDS,AXMOV CX,110H ;初始化,设定循环次数(CX)=272Delay1ms: PUSHF;循环体

POPF LOOPDelay1ms ;(CX)←(CX)-1,若(CX)≠0转Delay1msPRG 1MSENDP ENDPRG 1MS PROCFAR如果想延长1s时间,则需要执行上述程序1000次。可以通过双循环的方法来解决

。.MODELSMALL.STACK64.CODEPRG 1S

PROCFARMOVAX,@DATAMOVDS,AX如果想延长1s时间,则需要执行上述程序1000延时1ms程序段

MOV

BX,3E8H ;(BX)←1000Delay1s:

MOV CX,110HDelay1ms:PUSHF

POPF

LOOP Delay1ms

DEC BX ;(BX)←(BX)-1

JNZ Delay1s ;ZF=0时,转至Delay1s,即(BX)≠0时转

PRG

1S ENDP

END延时1ms程序段MOVBX,3E8H ;(BX【例3】假设有一16位二进制数位于内存数据段中,其偏移地址为0050H,将其转换为ASCII码,并将转换结果存放在该数据段中,其偏移地址为0052H,且连续存放,请编程实现。【例3】假设有一16位二进制数位于内存数据段中,其偏移地址为

.MODELSMALL

.STACK64

.DATA ORG0050H BinDat1DB27H,54H ASCDat DB6DUP(?)

.CODEBINToASCPRG PROCFAR

MOVAX,@DATA

MOVDS,AX .MODELSMALL

MOVSI,BinDat1

;需转换的数据的指针(SI)=0050H

MOVAX,[SI]

;(AX)←((SI)),取需转换的数据

MOVSI,ASCDat;(SI)←ASCDat,指向最后一个存放ASCII码数单元;存最低位数字

ADDSI,4

MOVBX,10T10toAsc:SUBDX,DX

;在字除法时,(DX)=0

DIVBX

;(AX)←(DX:AX)/(BX)

;(DX)←(DX:AX)%(BX)

MOVSI,BinDat1

ORDL,30H

;加30H,转换为ASCII码值

MOV[SI],DL ;保存数据

DECSI;修改地址指针(SI)←(SI)-1CMPAX,0;若(AX)>0,则继续循环

JAT10toAscBINToASCPRG

ENDP

ENDORDL,30H4子程序设计子程序是一个独立的程序段,确切地说,它是被其他程序(如主程序)调用的程序。一般是有公用性、重复性或有相对独立性的程序应设计成子程序,这种结构给程序设计与调试带来许多方便。4子程序设计子程序是一个独立的程序段,确切地说,它是子程序调用实际是程序的转移,但它与转移指令有所不同,转子程序CALL执行时要保护返回地址,而转移指令不考虑返回问题。每个子程序都有RET指令负责把推入堆栈的返回地址弹出送IP或CS:IP(段间返回),实现子程序返回。子程序设计与应用应注意的问题:(1)现场保护与恢复:调用子程序时,可能要使用被占用了的寄存器,子程序执行完毕返回时,要保证调用程序按原有状态继续正常执行,需要对这些寄存器的内容加以保护,称为现场保护。子程序执行完毕后再恢复被保护的寄存器的内容,称为现场恢复。子程序调用实际是程序的转移,但它与转移指令有所不同(2)参数传递:调用程序与子程序之间需要进行相关信息或数据的传递。将子程序需要从调用程序获取的参数称为入口参数,将子程序需要返回给调用程序的参数称为出口参数。寄存器传递:选定某些通用寄存器,但因寄存器数量有限,适合于参数较少的情况。存储单元(参数表)传递:适合于参数较多的情况,但要求事先在内存内建立一个参数表。堆栈传递:堆栈具有后进先出的特性,在多重调用中各重参数的层次很分明,适合于参数多且子程序有嵌套、递归调用的情况。(2)参数传递:调用程序与子程序之间需要进行相关信息或【例1】找出一个数据块中的最大数。其中,数据块的长度>1,并且放在内存2001H单元中,而数据块本身是从2002H单元开始存放的,最后,把找出的最大值放到2000H单元中,假设这段数据块中的数都是无符号的8位数,请设计成一段可调用的子程序。【例1】找出一个数据块中的最大数。其中,数据块的长.MODELSMALL.STACK64.CODEMAXPRG PROCFARMOVAX,@DATAMOVDS,AXMAX:PUSHF PUSH AX PUSH CX PUSH SI.MODELSMALLMAX:MOVSI,2001H;指针指向放数据块长度的单元MOVCL,[SI];取出来作为循环次数INCSI;指针指向第一个数MOVAL,00H ;设置最大值00MOVCH,00H ;初始化LP:CLC;清除进位位CMPAL,[SI];取出数与最大值比较JNCAA ;AL中数大,跳过去MOVAL,[SI];把大数放到AL中保存MOVSI,2001H;指针指向放数据块长度的单AA:INCSI;指针下移LOOPLP;次数减1,判循环结束否MOV[2000H],AL;把最大值放到指定单元保存POPSIPOPCXPOPAXPOPFRETMAXPRG ENDPENDAA:INCSI例2内存中有一数组,其首地址为ARRAY,求该数组所有元素之和(不超过16位数)并存于内存SUM单元中,请编写子程序实现。

.MODELSMALL.STACK64.CODEArraySumPRG PROCFARMOVAX,@DATAMOVDS,AXCLC ;CF=0 CMP CX,0 ;判断是否结束 例2内存中有一数组,其首地址为ARRAY,求该数组所JZ EXIT MOV AX,0 ;(AX)=0A_Sum:ADD AL,[SI];加数组中的一个元素

ADC AH,0 INC SI LOOP A_SumPOPFEXIT: RETArraySumPRG ENDPENDJZ EXIT第五章汇编语言程序设计课件

.MODELSMALL.STACK64.CODEArraySumPRG PROCFARMOVAX,@DATAMOVDS,AXPUSHFPUSHAXPUSHCXPUSHBPPUSHSIPUSHDI .MODELSMALLMOV SI,[BX] ;数组首地址((BX)+1:(BX))→(SI)MOV BP,[BX+2];数组长度单元地址((BX+3):(BX+2))→(BP)MOV CX,DS:[BP];数组长度((BP)+1:(BP))→(CX)MOV DI,[BX+4] ;存储和单元地址((BX+5):(BX+4))→DIA_Sum:ADD AX,[SI] ADD SI,2 LOOPA_Sum;循环求和

MOV [DI],AX ;存储和MOV SI,[BX]POPDIPOPSIPOPBPPOPCXPOPAXPOPFRETArraySumPRG ENDPENDPOPDI .MODELSMALL.STACK64.CODEArraySumPRG PROCFARMOVAX,@DATAMOVDS,AXPUSHF PUSHAX ;保护现场(AX),(BX),(CX),(BP)PUSHBX PUSHCX PUSHBP .MODELSMALL

MOV BP,SP MOV BX,[BP+14];取得数组长度地址参数

MOV CX,[BX] MOV BX,[BP+12];取累加和的单元地址参数

MOV SI,[BP+16];取数组的单元地址参数

MOV AX,0A_Sum:ADD AX,[SI] ;求和

ADD SI,2 MOV BP,SPLOOPA_Sum MOV [BX],AX ;保存和

POP BP ;恢复现场(BP),(CX),(BX),(AX) POP CX POP BX POP AX POPF RET 6;返回并废除地址参数ArraySumPRG ENDPENDLOOPA_Sum5查表程序设计采用查表法代替数据运算的方法。即先把全部函数值存放在微机的内存中,而工作时,程序只是用间址的方法取出变量对应的结果就可以了(使用XLAT指令)。建表的原则是方便地找到函数对应值,具体方法:一是表格的起始地址(或称基地址),二是某函数值案在表中的序号(或称索引值)。函数值的地址值即等于基地址加上索引值。基地址比较好办,只要找到空白单元区域,即可考虑开始存放该表。5查表程序设计采用查表法代替数据运算的方法。即先例从键盘上输入任意一个1位十进制数(0~9),用移位指令乘10,并将结果显示出来。NAMEEX1PAGE50,70DATSEGMENTPARA'DAT'BUFFDB4DUP(?)DATENDSSTACSEGMENTPARASTACK'STA'STA1DB100DUP(?)STACENDS例从键盘上输入任意一个1位十进制数(0~9),用CODESEGMENTPARA'CODE'ASSUMECS:CODE,DS:DATASSUMESS:STAC,ES:DATSTARTPROCFAR

PUSHDSXORAX,AXPUSHAX;返回DOS操作系统MOVAX,DATMOVDS,AX;设置DS值CODESEGMENTPARA'CODE'

CALLP1;调键盘输入子程序

CALLP2;调乘10子程序

CALLP3;调显示子程序RETLEASI,BUFF;建立缓冲区首址指针CALLP1;调键盘输入子程序LEP1PROC;键盘输入子程序RE:MOVAH,1INT21H

CMPAL,’0’JCRECMPAL,3AHJNCRE

ANDAL,0FHMOV[SI],AL;从键盘输入一个数并显示;数据输入合法否?若不合法,重新输入?;将输入数据转换为BCD码存缓冲区

MOVDL,0DHMOVAH,2INT21HMOVDL,0AHMOVAH,02HINT21HRETP1ENDP;回车换行符送显示MOVDL,0DH;回车换行符送显示P2PROC;乘10子程序

MOVAL,[SI];从缓冲区取数

SHLAL,1MOVBL,ALMOVCL,2SHLAL,CLADDAL,BL;乘10MOVAH,0

MOVBL,10DIVBLADDAH,30HADDAL,30HMOV[SI],ALMOV[SI+1],AHRETP2ENDP

;将积转换成ASCII码存缓冲区MOVAH,0;将积转换成ASCII码P3PROC;显示子程序

MOVDL,[SI]MOVAH,2INT21HMOVDL,[SI+1]MOVAH,2INT21HRETP3ENDPCODEENDSENDSTART编辑程序.ASMMASM.OBJLINK.EXE编辑程序.ASMMASM.OBJLINK.EXE汇编语言上机过程开机进行系统选择→DOS进入DOS环境C:\>C:\>CDMASM↙C:\MASM>EDIT↙进入编辑环境,输入程序,输入完毕存盘。汇编语言上机过程开机进行系统选择→DOS进入DOS环境ALT-F→NEW建立新文件

OPEN打开已有文件

SAVE保存

SAVEAS另存为

EXIT退出选择SAVE↙,命名EX1.ASM↙ALT-F→EXITALT-F→NEW建立新文件选择SAVE↙,命名回到DOS环境C:\MASM>MASMEX1.ASM↙3次回车,无错.0warnings0errors.C:\MASM>LINKEX1.ASM↙3次回车Running:EX1.EXE:EX1↙看结果!回到DOS环境C:\MASM>MASMEX1.第五章

汇编语言程序设计第五章

汇编语言程序设计程序是计算机命令(语句)的有序集合。

机器语言、汇编语言、高级语言机器语言是一种用二进制数表示指令和数据,能被机器直接识别的语言。

汇编语言弥补了机器语言的不足,采用助记符编程。但也是面对机器的,要求程序员对机器指令系统、内存空间分配了如指掌,地址是汇编语言关键所在,执行速度快,但可移植性差。高级语言是面向过程的,程序员没必要了解内存分配,更符合人的思维方式,执行速度相对慢一些,可移植性好。程序是计算机命令(语句)的有序集合。§5.1汇编语言的基本语法汇编语言源程序中的语句可以分为三种类型:指令语句,伪指令语句和宏指令语句。(1)指令语句:它是能产生目标代码,CPU可以执行的能完成特定功能的语句。(2)伪指令语句:它是一种不产生目标代码的语句,它仅仅在汇编过程中告诉汇编程序应如何汇编。伪指令语句是汇编程序在汇编时使用的。(3)宏指令语句:它是一种编程者利用伪指令语句自己定义的语句。§5.1汇编语言的基本语法汇编语言源程序中的语句1.伪指令的语句格式

1)标号标号名字段,它是任选字段。目标名后面不能用冒号“:”,标号名可以是常量名、变量名、过程名、结构名、记录名等。可以作为指令语句和伪指令语句的操作数,这时,标号名表示一个常量或存储器地址。1.伪指令的语句格式1)标号2)伪指令助记符或伪操作字段,不可省略。伪指令种类很多,如定义数据伪指令DB,DW,DD;段定义伪指令SEGMENT;定义过程伪指令PROC;…。它们是伪指令语句要求汇编程序完成的具体操作命令3)操作数本字段是否需要,需要几个,需要什么样的操作数等都由伪指令字段中伪指令来确定。操作数可以是一个常数(二进制、十进制、十六进制等)、字符串、常量名、变量名、标号、一些专用的符号(如BYTE,FAR,PARA等)。2)伪指令3)操作数4)注释任选字段,它必须以分号为开始,它的作用与指令语句的注释字段相同。2.常数、变量和标号常数、变量和标号是汇编语言能识别的数据项,它是指令和伪指令语句中操作数的基本组成部分。一个数据项包含有它的数值和属性两部分,这两部分对一条语句汇编成机器目标代码都有直接关系。4)注释2.常数、变量和标号常数、变1)常数常数是没有任何属性的纯数值。在汇编期间,它的值已能完全确定,且在程序运行中,它也不会发生变化。2)变量变量是代表存放在某些存储单元的数据,这些数据在程序运行期间随时可以修改。为了便于对变量的访问,它常常以变量名的形式出现在程序中,它可以认为是存放数据存储单元的符号地址。1)常数2)变量(1)变量的定义与预置:定义变量就是给变量分配存储单元,且对这个存储单元赋予一个符号名——变量名,同时将这些存储单元预置初值。定义变量是用数据定义伪指令DB,DW,DD等。例如:VAR_DATA SEGMENTDATA1DB 12HDATA2DB 34HDATA3DW 5678HVAR_DATA ENDS(1)变量的定义与预置:定义变量就是给变量分配存储单元,(2)数据定义伪指令:为数据项分配存储单元并预置初值。变量名表达式1,表达式2,…①数值表达式。DA_BYTE DB50H,50

DA_WORD DW 0A3F1H,4981H

(2)数据定义伪指令:为数据项分配存储单元并预置初值。变量名②?表达式:不带引号的?表示可预置任何内容。DA_B DB ?,?DA_W DW ?,?③字符串表达式:对于DB伪指令,为字符串中每一个字符分配一个字节单元。字符串必须是用引号括起来且不超过255个字符。字符串自左至右以字符的ASCII码按地址递增的排列顺序依次存放。STRING1DB 'ABCDEF'STRING2 DW 'AB','CD','EF'STRING3 DD'AB','CD'②?表达式:不带引号的?表示可预置任何内容。DA_B DB第五章汇编语言程序设计课件④带DUP表达式:DUP是定义重复数据操作符。变量名表达式1,DUP(表达式2)D_B1DB20H DUP(?)D_B2DB10HDUP('ABCD')D_W1DW10HDUP(4)④带DUP表达式:DUP是定义重复数据操作符。变量名表达3)标号标号是一条指令目标代码的符号地址,它常作为转移指令(含子程序调用指令)的操作数。LOP1: … …

LOOP LOP1 … JNE NEXT …NEXT: …(1)段属性(2)偏移量属性:(3)距离属性:①NEAR(近);②FAR(远)3)标号LOP1: …(1)段属性(1)SEG

格式:SEG <符号名>

功能是求符号名所在段的段基址。(2)OFFSET

格式:OFFSET <符号名>

功能是求符号名所在段的偏移地址。(3)TYPE

格式:TYPE<符号名>功能是获得符号名类型值。3.运算符(1)SEG 3.运算符(4)SIZE

格式:SIZE <符号名>功能是获得为符号名分配的字节数。为符号名定义的数据项必须是用重复格式DUP()定义的。(5)PTR

格式:<类型>PTR<符号名>功能是定义符号名为新类型。如,设内存变量D1是字节属性,把它的两个字节内容送到AX中MOVAX,WORDPTRD1(4)SIZEMOVAX,WORDPTRD1§5.2伪指令伪指令没有对应的机器指令,它不是由86系列CPU来执行,而是由MASM-86识别,并完成相应的功能。它在很大程度上规定了MASM-86的性能,因此也可称之为汇编命令。1.符号定义伪指令(赋值语句)1)EQU格式:<名字>EQU<表达式>2)=格式:<名字>=<表达式>§5.2伪指令伪指令没有对应的机器指令,它2.内存数据定义伪指令1)字节定义伪指令DB格式:[名字]DB<表达式或数据项表>3)4字节定义伪指令DD格式:[名字]DD<表达式或数据项表>2)字定义伪指令DW格式:[名字]DW<表达式或数据项表>2.内存数据定义伪指令1)字节定义伪指令DB3)4字3.段定义伪指令1).SEGMENT/ENDS格式:<段名> SEGMENT [定位方式][连接方式][‘类型名’] … <段名> ENDS段定义伪指令为程序的汇编和连接说明了段名、段的各种属性以及段的开始和结束。段名是自定义符,开始的段名与结束的段名必须相同。段的长度不超过64KB。3.段定义伪指令1).SEGMENT/END(1)定位方式(定位类型Align):定位方式指定段的起始地址边界,方式有4种。PAGE——指定起始地址的低8位是0,即其值能被256整除(称为页对齐)。PARA——指定起始地址的低4位是0,即其值能被16整除(称为段对齐)。这是系统隐含定位方式。WORD——指定起始地址的最低位是0,即其值能被2整除(称为字对齐)。BYTE——指定起始地址是任意值(称为字节对齐)。(1)定位方式(定位类型Align):定位方式指定段的起始(2)连接方式(组合类型):连接方式告诉连接程序,本段与其他段可按某种方式连接,它有6种选择。PUBLIC——告诉连接程序本段与其他同名同类别的段连接起来,公用一个段的起始地址,形成一个物理段。STACK——表示本段是堆栈段,连接方式同PUBLIC,连接后的段起始地址在SS寄存器中。连接程序要求源程序至少要有一个堆栈段,否则提示错误,此时,系统取约定堆栈段值。

(2)连接方式(组合类型):连接方式告诉连接程序,本段与其他空缺(NONE)——表示本段不与任何段连接,这是系统隐含连接方式。COMMON——表示本段与同名同类型的段共用同一段起始地址,即同名同类段相重叠,段的长度是最长段的长度。MEMORY——表示本段在连接时定位在所有段之上,即高地址处。AT表达式——表示本段定位在表达式值指定的段地址处。

空缺(NONE)——表示本段不与任何段连接,这是系2).ASSUME格式:ASSUME段寄存器:段定义名1[,段寄存器:段定义名2,…]ASSUME伪指令告诉汇编程序,将某一个段寄存器设置为存放某一个逻辑段的段地址,即明确指出源程序中的逻辑段与物理段之间的关系。当汇编程序汇编一个逻辑段时,即可利用相应的段寄存器寻址该逻辑段中的指令或数据。在一个源程序中,ASSUME伪指令定义符应该放在可执行程序开始位置的前面。ASSUME伪指令只是通知汇编程序有关段寄存器与逻辑段的关系,并没有给段寄存器赋予实际的初值。用户需要通过指令给有关段寄存器赋值。2).ASSUME.STACK64.DATADATA1DB15HDATA2DB29HSUMDB?.CODE3.简化段定义“.CODE”、“.DATA”和“.STACK”来分别对应寄存器CS、DS和SS。例如以下代码片段:MAINPR

温馨提示

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

评论

0/150

提交评论