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

下载本文档

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

文档简介

汇编语言程序设计5.1程序设计概述5.2汇编,链接和运行程序5.3模块化的程序设计5.4汇编语言程序设计的基本方法内容与要求:掌握汇编语言的基本语法、语句、操作数的寻址方式与汇编表示、常量与数值表达式,标号、变量与地址表达式。2.掌握顺序、分支、循环程序设计的基本方法和一般技巧。3.掌握子程序与堆栈技术。4.了解宏汇编和宏指令的应用。5.1程序设计概述

1.机器语言(MachineLanguage)

机器语言是一种用二进制表示指令和数据,能被机器直接识别的计算机语言。它的缺点是不直观,不易理解和记忆,因此编写、阅读和修改机器语言程序都比较繁琐。但机器语言程序是计算机惟一能够直接理解和执行的程序,具有执行速度快、占用内存少等特点。

2.高级语言(HighLevelLanguage)

如果说机器语言是面向机器的,那么高级语言(如BASIC,FORTRAN等)则是“面向过程”的语言。利用这些语言编程,程序员可以完全不考虑机器的结构特点,不必了解和熟记机器的指令系统,仅使用一些接近人们书写习惯的英语和数学表达式形式的语句去编制程序。这样编写的程序与问题本身的数学模型之间有着良好的对应关系,可在各种机器上通用(不同机器之间仅做少量修改)。但是,这种用高级语言编写的源程序并不能在机器上直接执行,需要被翻译成对应的目标程序(即机器语言程序),机器才能运行。把具有这种翻译作用的程序称为解释程序或编译程序,见图5.1。

由于高级语言程序是在未考虑机器的结构特点的条件下编写的,因而它就不能充分利用某种具体CPU所具有的某些特性,而通过编译或解释程序生成的目标程序往往比较冗长,占有较多的内存空间,执行时间也比较长,这就限制了它在某些场合下的运用。例如,实时的数据采集、检测和在线的实时控制等,往往要求程序的目标代码尽可能少占内存并有尽可能快的执行速度,在这些场合下,使用高级语言编写的程序常常不能满足要求。3.汇编语言(AssemblyLanguage)

汇编语言是一种采用助记符表示的程序设计语言,即用助记符来表示指令的操作码和操作数,用标号或符号代表地址、常量或变量。助记符一般都是英文字的缩写,以方便人们书写、阅读和检查。实际上,用汇编语言编写的汇编语言源程序就是机器语言程序的符号表示,汇编语言源程序与其经过汇编所产生的目标代码程序之间有明显的一一对应关系,故也称汇编语言为符号语言。

用汇编语言编写程序能够直接利用硬件系统的特性(如寄存器、标志、中断系统等)直接对位、字节、字寄存器或存储单元、I/O端口进行处理,同时也能直接使用CPU指令系统和指令系统提供的各种寻址方式,编制出高质量的程序,这样的程序不但占用内存空间少,而且执行速度快。当然,由于源程序和所要解决的问题的数学模型之间的关系不够直观,使得汇编语言程序设计需要较多的软件开发时间,也增加了程序设计过程中出错的可能性。用汇编语言编写的源程序也需要翻译成目标程序才能被机器执行。这个翻译过程称为汇编,完成汇编任务的程序称为汇编程序,见图5.2。

图5.2汇编程序的功能示意图

汇编程序是最早也是最成熟的一种系统软件。它除了能够将汇编语言源程序翻译成机器语言程序这一主要功能外,还能够根据用户的要求自动分配存储区域(包括程序区、数据区、暂存区等);自动地把各种进位制数转换成二进制数,把字符转换成ASCII码,计算表达式的值等;自动对源程序进行检查,给出错误信息(如非法格式,未定义的助记符、标号,漏掉操作数等)等。具有这些功能的汇编程序又称为基本汇编(或小汇编ASM)。在基本汇编的基础上,进一步允许在源程序中把一个指令序列定义为一条宏指令的汇编程序,就叫做宏汇编(MASM)。它包含全部ASM功能,还增加了宏指令、结构、记录等高级汇编语言功能。5.2

汇编,链接和运行程序5.3

模块化的程序设计

(从功能分析——战略上看);onefilewillcontainthemainmodule:

EXTRN SUBPROG1:FAR

EXTRN SUBPROG2:FAR

PUBLICVALUE1,VALUE2,SUM,PRODUCT ;declaredataheretobeshared

.MODELSMALL;

.STACK64;

.DATA VALUE1 DW 2050 VALUE2 DW 500 SUM DW 2DUP(?) PRODUCT DW 2DUP(?);

.CODEMAIN PROC FAR

MOV AX, @DATA MOV DS, AX

CALL SUBPROG1 ;callsubprog1toaddvalue1+value2

CALL SUBPROG2 ;callsubprog2tomulvalue1*value2 MOV AH, 4CH INT 21H MAIN ENDP

END MAIN ;thisprogramfindsthesumoftwoexternallydefinedwordsandstores;thesuminalocationdefinedbythecallingmodule

EXTRNVALUE1:WORD

EXTRNVALUE2:WORD

EXTRNSUM:WORD

PUBLICSUBPROG1

.MODELSMALL

.CODESUBPROG1 PROC FAR SUB BX,BX;initializecarrycount MOV AX,VALUE1 MOV DX,VALUE2 ADD AX,DX ADC BX,00 MOV SUM,AX MOV SUM+2,BX

RET

SUBPROG1 ENDP END;thisprogramfindstheproductoftwoexternallydefinedwordsandstorestheproductinalocationdefinedbythecallingmodule

EXTRN VALUE1:WORD

EXTRN VALUE2:WORD

EXTRN PRODUCT:WORD

PUBLICSUBPROG2

.MODELSMALL

.CODESUBPROG2 PROC FAR MOV AX,VALUE1 MOV CX,VALUE2 MUL AX,CX MOV PRODUCT,AX MOV PRODUCT+2,DX

RETSUBPROG2 ENDP

END注意:1.EXTRN在调用其他模块的过程中,必须用伪指令EXTRN告诉汇编程序EXTRN后的过程或变量不在此模块中。2.PUBLIC在说明变量或过程的模块中,必须用伪指令PUBLIC告诉链接程序此变量或过程能被其他模块所访问。3.CALL4.RET5.C:>LINKPROGRAM1.OBJ+PROGRAM2.OBJ+…+PROGRAMn.OBJ5.3汇编语言程序设计的基本方法(战术上看)

5.3.1程序设计步骤 1.问题的定义 2.算法及表示方法 3.选择适当的指令 4.编写程序

5.3.2结构化程序设计

1.顺序结构 2.分支结构 3.循环结构 4.子程序设计5.4上机过程

1.编辑程序 2.汇编源程序 3.链接程序 4.调试源程序5.3.1程序设计步骤

1.问题的定义

仔细思考程序所要解决的问题,即用自然语言描述“做什么?以及程序做这些工作时的时序” 如:1.从传感器读取温度值。

2.加上调整因子。

3.将结果存储在存储单元里。

2.算法及表示方法

用来表示程序设计问题的操作序列成为算法,即“怎样做?”。表示方法:1)流程图

2)伪指令3.选择适当的指令(按功能)

一、数据传送类指令二、算术运算指令三、位操作指令四、串操作指令五、程序转移指令六、处理机控制指令4.编写程序(从算法到程序)4.编写程序将算法转换成汇编语言(1)建立算法使用的数据结构

1)数据将存放在存储器还是存放在寄存器中

2)数据类型是字节、字或双字?

3)有多少数据项?

4)数据为无符号数还是符号数?(2)在代码段开始处写出变量、段寄存器、外围设备等所需要的初始化指令。 初始化表:数据段寄存器DS 堆栈段寄存器SS 附加段寄存器ES 堆栈段指针SP 8255A可编程并行端口 8259A优先级中断控制器 8254可编程计数器 8251可编程串行端口 初始化数据变量 设置中断允许标志(3)选择实现算法中每一主要动作所需要的指令,并决定数据在这些指令中的存放形式。(4)按照主要指令的要求,用MOV指令或其他的指令把数据送到正确的位置。例题:1.定义问题:

已知某日的最高温度和最低温度,要求计算这一天的平均温度。2.算法设计:最高温度加最低温度将和除以2得到平均温度3.数据结构:

DATASEGMENTHI_TEMPDB92H;实际值可能是从传感器读取的数值

LO_TEMPDB52H AV_TEMPDB?

DATAENDS4.初始化表:

MOVAX,DATA MOVDS,AX5.选择指令:选择算法中每一主要动作所需的指令(按功能选择指令),并决定数据在这些指令中的存放形式,最后则按照指令的要求,用MOV或其他的指令把数据传送的正确的位置。

ADDdest,source;查指令表并阅读细节

ADC

dest,source;dest=dest+source+CFDIV

source;DIV02immedmodenotallowed!!6.编写程序:DATASEGMENTHI_TEMPDB92HLO_TEMPDB52HAV_TEMPDB?DATAENDSCODE SEGMENTMAIN PROC FAR

ASSUME CS:CODE,DS:DATA MOV AX,DATA MOV DS,AX MOV AL,HI_TEMP ADD AL,LO_TEMP MOV AH,00H ADC AH,00H MOV BL,02 DIV BL MOV AV_TEMP,AL

MOV 4CH INT 21HMAIN ENDPCODE ENDS

ENDMAIN5.3.2结构化程序设计 1.顺序结构Readtemperaturefromsensor

Addcorrectionfactorof+7

Storecorrectedvalueinmemory例题:1.定义问题: 将ASCII码‘47’转换成压缩BCD码。2.算法设计: 转换第一个ASCII码到非压缩BCD数。 转换第二个ASCII码到非压缩BCD数。 将第一个BCD数的低半字节左移四位。 在一个字节中组合两个BCD数。3.数据结构: DATA SEGMENT VAL_ASC DB‘47’ VAL_BCD DB? DATA ENDS4.初始化表:

MOVAX,DATA

MOVDS,AX5.选择指令:1)用AND指令完成屏蔽操作。 AND dest,source ASCII4 00110100 屏蔽00001111 结果000001002)用循环位移指令左移四位。 ROL dest,CL3)用OR指令组装字节 OR dest,source OR AL,BL6.编写程序:Key

ASCII

UnpackedBCD

PackedBCD434000001007370000011101000111(47H); ORG 0010HVAL_ASC DB ‘47’VAL_BCD DB ?; MOV AX, WORDPTRVAL_ASC AND AX, 0F0FH XCHG AH, AL MOV CL, 4 ROL AH, CL OR AL, AH MOV VAL_BCD, AL;2.分支结构(IF-THEN-ELSE)问题定义:

有一台控制印刷线路板制造机器的8086微机。其作用是检查温度传感器,然后按照从传感器读到的温度值打开绿灯或黄灯。如果温度低于300C,则打开黄灯以告诉操作员溶液的温度不够。如果温度高于或等于300C,则打开绿灯。算法设计:

输入温度值 IF温度<300CTHEN 打开黄灯 ELSE 打开绿灯 读传感器3.数据结构:

AL(INAL,DX)4.初始化表:

MOV DX,0FFFEH;pointDXtoportcontrol MOV AL,99H;registerandloadcontrolword OUT DX,AL;toinitializeports5.选择指令:

IN OUT CMP Jcc6.编写程序:;PORTS:UseFFF8H-temperatureinput;FFFAH-lampcontroloutput(yellow=bit0,green=bit1) CODE SEGMENT

ASSUME CS:CODE;initialize8086portFFFAHasoutputport,FFF8Hasinput. MOV DX,0FFFEH;pointDXtoportcontrol MOV AL,99H;registerandloadcontrolword OUT DX,AL;toinitializeports MOV DX,0FFF8H IN AL,DX

CMP AL,30

JB YELLOW;iftemp<30thenlightyellow;lamp

JMP GREEN;elselightgreenlampYELLOW: MOV AL,01H;loadcodetolightyellowlamp MOV DX,0FFFAH;pointDXatoutputport OUT DX,AL;sendcodetolightyellowlamp JMP EXIT;gotonextmainlineinstructionGREEN: MOV AL,02H MOV DX,0FFFAH OUT DX,ALEXIT: MOV DX,0FFFCH;nextmainlineinstruction IN AL,DX ;readphsensorCODE ENDS END输入温度值IF温度〉=300CTHEN打开绿灯ELSE打开黄灯读传感器

CMP AL,30

JAE GREEN

JMP YELLOWGREEN: MOV AL,02H MOV DX,0FFFAH OUT DX,AL JMP EXITYELLOW: MOV AL,01H MOV DX,0FFFAH OUT DX,ALEXIT: MOV DX,0FFFCH IN AL,DXCODE ENDS END2.多重IF-THEN-ELSE结构:IFconditionTHEN statement(s)1ELSE IFconditionTHEN statement(s)2 ELSEstatement(s)3问题定义:

有一台控制印刷线路板制造机器的8086微机。其作用是检查温度传感器,然后按照从传感器读到的温度值打开绿灯、黄灯或红灯。如果温度低于300C,则打开黄灯以告诉操作员溶液的温度不够。如果温度高于或等于300C但低于400C,则打开绿灯,否则,打开红灯。算法设计:

输入温度值 IF温度<300CTHEN 打开黄灯 ELSEIF温度<400CTHEN 打开绿灯 ELSE打开红灯 读传感器CODE SEGMENT

ASSUME CS:CODE MOV DX,0FFFEH MOV AL,99H OUT DX,AL MOV DX,0FFF8H IN AL,DX MOV DX,0FFFAH

CMP AL,30

JB YELLOW

CMP AL,40

JB GREENRED: MOV AL,04H OUT DX,AL JMP EXITYELLOW: MOVAL,01H OUT DX,AL JMP EXITGREEN: MOVAL,02H OUT DX,ALEXIT: MOVDX,0FFFCH IN AL,DXCODE ENDS END3.循环结构

WHILE–DO--LOOPWHILEconditionDOstatement(s)WHILEnot24samplesDOReaddatasamplefromsensorAddcorrectionfactorof+7StoreresultinmemoryWait1hour.例1:定义问题

假设在一个化学处理控制过程中,只有当溶液温度上升到1000C后,才能继续进行下一步的处理。如果溶液温度低于1000C,则需打开一个加热器并等待温度上升到1000C。如果溶液温度等于或者高于1000C,则继续进行下一步的处理。由于打开加热器前需要测设条件(温度),因此WHILE-DO结构适合于解决这样的问题。当然如果溶液的温度因过度加热而足够高时,则不需要打开加热器。2.算法设计(a)

输入温度值 WHILE温度>=100 DO 关闭加热器 打开加热器3.数据结构

AL(INAL,DX)4.初始化表

MOV DX,0FFFEH;initializeportFFFAHforoutput MOV AL,99H;andportFFF8Hforinput OUT DX,AL5.选择指令

IN CMP Jcc OUT6.编写程序;ports:usesFFF8Hfortemperaturedatainput;FFFAHforheatercontroloutput,0=off,1=onCODE SEGMENT

ASSUME CS:CODE MOV DX,0FFFEH;initializeportFFFAHforoutput MOV AL,99H;andportFFF8Hforinput OUT DX,ALTEMP_IN: MOV DX,0FFF8H;pointatinputport IN AL,DX;inputtemperauredata CMP AL,100;iftemp>=100then JAE HEATER_OFF;turnheateroff MOV AL,01H;elseloadcodeforheateron MOV DX,0FFFAH ;pointDXtooutputport OUTDX,AL;turnheateron JMPTEMP_IN;WHILEtemp<100read;tempagainHEATER_OFF:MOVAL,00H;loadcodeforheateroff MOVDX,0FFFAH;pointDXtooutputport OUTDX,AL;turnheateroffCODE ENDS END (a)加热器控制程序清单算法设计(b)

输入温度值 WHILE温度<100

DO 打开加热器 关闭加热器TEMP_IN: MOV DX,0FFF8H IN AL,DX CMP AL,100 JB HEATER_ON JMP HEATER_OFFHEATER_ON: MOV AL,01H MOV DX,0FFFAH OUT DX,AL JMP TEMP_INHEATER_OFF: MOVAL,00H MOV DX,0FFFAH OUT DX,ALCODE ENDS END3.循环结构: REPEAT—UNTIL

REPEAT 动作 UNTIL某些条件实现REPEAT

Getdatasamplefromsensor

Addcorrectionof+7

Storeresultinamemorylocation

Wait1hourUNTIL24samplestaken例1:1)问题定义:

许多与微机接口的系统的工作是首先在并行信号线上输出数据,然后再输出以单独信号用以指示有效数据在并行线上。这个数据准备信号通常被称为选通。一个ASCⅡ编码计算机键盘就是一种选通数据系统的例子。下图说明了这种键盘的并行数据线和选通线是怎样与微机端口连接的。当在键盘上敲入某个键时,键盘中的电路将检测敲入的键,然后将该键的ASCⅡ码发送到连接端口FFF8H的8位数据线上。当经过一段时间数据已驻留在这些数据线上后,键盘中的电路发出一个压键选通信号,以指示8位数据线上的数据已经有效。选通信号可以是有效高信号或有效低信号。对于本例假设一个有效ASCⅡ码已在并行数据线上时,选通信号趋向于高。2)算法设计REPEAT读键盘选通信号UNTIL选通信号=1从键盘读ASCII码3)数据结构

AL(INAL,DX)4)初始化表

MOVDX,0FFFAH

;pointDXatstrobeport5)选择指令

IN Jcc IN6)编写程序;usesFFFAH-StrobesignalinputonLSB;FFF8H-ASCIIdatainputportCODE SEGMENT

ASSUME CS:CODE MOVDX,0FFFAH;pointDXatstrobeportLOOK:IN AL,DX;readkeyboardstrobe ANDAL,01;maskextrabitsandsetflags JZ LOOK;ifstrobeislowthenkeeplooking MOVDX,0FFF8H;elsepointDXatdataport IN AL,DX;readinASCIIcodeCODE ENDS END例2:1)问题定义

要求把通货膨胀因子03H加入到具有8个元素价格数组的每个价格中,而其中每一个价格是以压缩式BCD(每个字节中有两个BCD数)形式存放在一个字节存储单元中,价格的范围在1到99分之间。2)算法设计:REPEAT

从数组中得到一价格 加入通货膨胀因子 结果调整为正确的BCD数 将结果放回数组中UNTIL

所有价格均已处理ARRAYS SEGMENT COST DB20H,28H,15H,26H,19H,27H,16H,29H PRICEDB36H,55H,27H,42H,38H,41H,29H,39HARRAYS ENDS4)初始化表

MOV AX,ARRAYS MOV DS,AX3)数据结构5)选择指令:

MOV ADD DAA Jcc6)编写程序:ARRAYS SEGMENT COSTDB20H,28H,15H,26H,19H,27H,16H,29H PRICEDB36H,55H,27H,42H,38H,41H,29H,39HARRAYS ENDSCODE SEGMENT

ASSUMECS:CODE,DS:ARRAYSSTART: MOV AX,ARRAYS MOV DS,AX LEA BX,PRICES MOV CX,0008HDO_NEXT: MOV AL,[BX] ADD AL,03H DAA MOV [BX],AL INC BX DEC CX JNZ DO_NEXTCODE ENDS ENDSTART4.子程序设计:(1)模块化的程序设计;onefilewillcontainthemainmodule:

EXTRN SUBPROG1:FAR

EXTRN SUBPROG2:FAR

PUBLICVALUE1,VALUE2,SUM,PRODUCT ;declaredataheretobeshared

.MODELSMALL;

.STACK64;

.DATA VALUE1 DW 2050 VALUE2 DW 500 SUM DW 2DUP(?) PRODUCT DW 2DUP(?);

.CODE MAIN PROC FAR MOV AX,@DATA MOV DS,AX

CALL SUBPROG1 ;callsubprog1toaddvalue1+value2

CALL SUBPROG2 ;callsubprog2tomulvalue1*value2 MOV AH,4CH INT 21H MAIN ENDP

END MAIN ;thisprogramfindsthesumoftwoexternallydefinedwordsandstores;thesuminalocationdefinedbythecallingmodule

EXTRNVALUE1:WORD

EXTRNVALUE2:WORD

EXTRNSUM:WORD

PUBLICSUBPROG1

.MODELSMALL

.CODESUBPROG1 PROC FAR SUB BX,BX;initializecarrycount MOV AX,VALUE1 MOV DX,VALUE2 ADD AX,DX ADC BX,00 MOV SUM,AX MOV SUM+2,BX

RET

SUBPROG1 ENDP END;thisprogramfindstheproductoftwoexternallydefinedwordsand;storestheproductinalocationdefinedbythecallingmodule

EXTRNVALUE1:WORD

EXTRNVALUE2:WORD

EXTRNPRODUCT:WORD

PUBLICSUBPROG2

.MODELSMALL

.CODESUBPROG2 PROC FAR MOV AX,VALUE1 MOV CX,VALUE2 MUL AX,CX MOV PRODUCT,AX MOV PRODUCT+2,DX

RETSUBPROG2 ENDP

END(2)调用过程近过程的调用1)运行机制2)数据保存例题:1.问题定义:

假设从一压力传感器读取100个数据字的程序,要求每隔1ms从传感器读取一个数据字,然后屏蔽每个字的高4位并把结果放在一个数组中。2.算法设计:

初始化 REPEAT 从端口(传感器)读入数据 屏蔽高半字节 存入数组中 等待1ms过程 UNTIL读入100个字节算法设计:

《采样数据程序〉

初始化数据段寄存器,DS 初始化堆栈段寄存器,SS 初始化指向数组的指针,SI 初始化计数器,BX REPEAT 等待1ms过程 读端口 初始化计数器CX 屏蔽高半字节 REPEAT 存入数组中 减量CX

等待1ms过程 UNTILCX=0 增量指针,SI 减量计数器,BX UNTILBX=03.选择指令:

IN AND CALL INC DEC Jcc4.数据结构: AL DW 100DUP(?)5.初始化表:

初始化数据段寄存器,DS 初始化堆栈段寄存器,SS 初始化指向数组的指针,SI 初始化计数器,BX 初始化计数器,CX6.编写程序PRESSURE_PORTEQU0FFF8HDATA SEGMENT PRESSURE DW100DUP(?) SAMPLE EQU(($-PRESSURE)/2)DATA ENDSSTACK SEGMENT

DW40DUP(0)STACK ENDSCODE SEGMENT

ASSUME CS:CODE,DS:DATA,SS:STACKSTART: MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX LEA SI,PRESSURE MOV BX,SAMPLE MOV DX,PRESSURE_PORTNEXT_VAL: IN AX,DX AND AX,0FFFH MOV [SI],AX CALL WAIT_1MS INC SI INC SI DEC BX JNZ NEXT_VALSTOP: NOPWAIT_1MS PROC NEAR ;时钟周期数(5MHZ): MOV CX,295 ;4=C0HERE: LOOP HERE ;17or5

RET ;CT=C0+17N-12WAIT_1MS ENDP ;N=(CT-C0+12)/17CODE ENDS ;N=(5000-4+12)/17

ENDSTART ;=295

以1ms时间间隔读取100个采样数据的汇编语言程序2)数据保存 MULTO PROCNEAR PUSHF PUSHAX PUSHBX PUSHCX .. POP CX POP BX POP AX POPF RET MULTO ENDP(3)调用过程的参数传递

当调用一过程时,经常需要把一些数据值或地址传递到过程中,另外过程也经常需要把一些数据值或地址传回到主程序。这些在主程序和过程之间来回传递的数据值或地址通常被称为参数(parameters)。 传递参数的四种主要途径是: 1在寄存器中 2在用名字存取的存储器中 3用指针 4用堆栈用寄存器传递参数实例:问题定义:

要求将压缩的BCD数17转换成等价的二进制数。算法设计: 将BCD数17分裂成两个半字节 保存低半字节(不需乘1) 用0AH乘高半字节 将结果和低半字节相加例如:4596=4*1000+5*100+9*10+6*1 1000=03E8H 4000=4*03E8H=0FA0H 100=0064H 500=5*0064H=01F4H 10=000AH 90=9*000AH=005AH 1=0001H 6=1*0001H=0006H 4596 11F4HDATA SEGMENT BCD_IN DB17H BIN_VAL DB?DATA ENDSSTACK SEGMENT

DW 100DUP(0)STACK ENDSCODE SEGMENT

ASSUMECS:CODE,DS:DATA,SS:STACKSTART: MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX MOV AL,BCD_IN CALL BCD_BIN MOV BIN_VAL,AL NOP

BCD_BIN PROCNEAR PUSHF PUSH BX PUSH CX MOV BL,AL AND BL,0FH AND AL,0F0H MOV CL,04 ROR AL,CL MOV BH,0AH MUL BH ADD AL,BL POP CX POP BX POPF

RETBCD_BIN ENDPCODE ENDS

ENDSTART

(a)用寄存器传递参数实例2.用一般存储单元传递参数DATA SEGMENT BCD_IN DB17H BIN_VAL DB?DATA ENDSSTACK SEGMENT

DW 100DUP(0)STACK ENDSCODE SEGMENT

ASSUMECS:CODE,DS:DATA,SS:STACKSTART: MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX CALL BCD_BIN NOP NOPBCD_BIN PROCNEAR PUSHF PUSH AX PUSH BX PUSH CX MOV AL,BCD_IN MOV BL,AL AND BL,0FH AND AL,0F0H

MOV CL,04 ROR AL,CL MOV BH,0AH MUL BH ADD AL,BL MOV BIN_VALUE,AL POP CX POP BX POP AX POPF

RETBCD_BIN ENDP CODE ENDS

ENDSTART

(b)用有名存储单元传递参数的实例3.用指针传递参数

指针方法可以传递指向数据存放在任何存储单元的过程指针,也能传递指向零散值或指向数组或串的指针,因而这种方法具有更大的灵活性。DATA SEGMENT BCD_IN DB17H BIN_VAL DB?DATA ENDSSTACK SEGMENT

DW 100DUP(0)STACK ENDSCODE SEGMENT

ASSUMECS:CODE,DS:DATA,SS:STACKSTART: MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX MOV SI,OFFSET BCD_IN MOV DI,OFFSET BIN_VAL

CALL

BCD_BIN NOPBCD_BIN

PROC

NEAR PUSHF PUSH AX PUSH BX PUSH CX MOV AL,[SI] MOV BL,AL AND BL,0FH

AND AL,0F0H MOV CL,04 ROR AL,CL MOV BH,0AH MUL BH ADD AL,BL MOV [DI],AL POP CX POP BX POP AX POPF

RETBCD_BIN ENDP (c)用指向有名存储单元CODE ENDS 的指针传递参数实例

ENDSTARTC语言程序:/*headcount=5*/#include<stdio>/*&headcount=404*//*present=404*/Voidmain()/**present=5*/{/*&present=406*/ int headcount=5; int *present=&headcount; printf(“headcount=%d\n&headcount=%d\npresent=%d\n *present=%d\n&present=%d\n”,headcount, &headcount,present,*present,&present);} DATA SEGMENT headcount DW 5 present DW OFFSETheadcount DATA SEGMENT CODE SEGMENT ASSUMECS:CODE,DS:DATA START: MOV AX, DATA MOV DS, AX MOV BX, present MOV AX, [BX] … CODE ENDS END START 4.用栈传递参数

为了用栈传递参数到一过程,在主程序中的过程调用之前,应把这些参数压进栈的某个地方,然后过程中的指令按需从栈中读取参数。同理,过程也把传回调用程序的参数写入栈中,然后主程序中的指令把这些参数读出。DATA SEGMENT BCD_IN DB17H BIN_VAL DB?DATA ENDSSTACK SEGMENT DW 100DUP(0)STACK ENDSCODE SEGMENT

ASSUMECS:CODE,DS:DATA,SS:STACKSTART: MOV AX,DATA MOV DS,AX

MOV AX,STACK

MOV SS,AX MOV AL,BCD_IN

PUSH AX CALL BCD_BIN

POP AX

MOV BIN_VAL,AL NOPBCD_BIN PROCNEAR PUSHF PUSH AX PUSH BX PUSH CX PUSH BP

MOV BP,SP MOV AX,[BP+12]

MOV BL,AL AND BL,0FH AND AL,0F0H MOV CL,04 ROR AL,CL MOV BH,0AH MUL BH ADD AL,BL

MOV [BP+12],AL ;BP缺省段为SS POP BP POP CX POP BX POP AX POPF

RETBCD_BIN ENDP CODE ENDS

ENDSTART (d)用栈传递参数实例#include<stdio.h>int tempc,tempfint c2f(intc);void get_temp(int*ptr); void main(){ get_temp(&tempc); tempf=c2f(tempc); printf(“ThetemperatureinCelsiusis%d\n”,temp); printf(“ThetemperatureinFahrenheitis%d\n”,temp);}int c2f(intc){ int f; f=9*c/5+32; return(f);}Voidget_temp(int*ptr){ printf(“PleaseentertheCelsiustemperature./n”); scanf(“%d”,ptr);}

程序举例:说明、调用和定义C函数模板参数传递小结:

在调用程序和过程之间可以用(1)寄存器、(2)指定存储单元(用名字或指针存取)或者(3)栈传递参数。选择哪种方法很大程度上依赖于特定程序,没有标准规则,不过有几条建议。对于少量参数传递的简单程序,使用寄存器通常是最容易的方法,对于向/从过程传递数组或其他数据结构,则用寄存器传递指向这些数据结构开始地址的指针,如前面已解释过的,传递指针到过程比过程用名字直接存取数据结构要灵活的多。 对于多用户程序中的过程,从高级语言中调用的过程或过程调用自身,应该在栈中传递参数。当编写在栈中传递参数的程序中,应该借助如上图所示中的栈状态图帮助你记录当前栈中任何内容的位置。5.5常用系统功能调用和BIOS中断调用

微型计算机系统(IBMPC及兼容机)为汇编用户提供了两个程序接口,一个是DOS系统功能调用,另一个是ROM中的BIOS(BasicInput/OutputSystem)。系统功能调用和BIOS由一系列的中断服务子程序构成,但调用与返回不是使用子程序调用指令CALL和返回指令RET,而是通过软中断指令INTn和中断返回指令IRET调用和返回的。DOS系统功能调用和BIOS的服务子程序,使得程序设计人员不必涉及硬件就可以使用系统的硬件,尤其是I/O的使用与管理。DifferencebetweenINTandCALLinstructionsA“CALLFAR”instructioncanjumptoanylocationwithinthe1megabyteaddressrangeofthe8086/8088CPU,but“INTnn”goestoafixedmemorylocationintheinterruptvectortabletogettheaddressoftheinterruptserviceroutine.A“CALLFAR”instructionisusedbyprogrammerinthesequenceofinstructionsintheprogrambutanexternallyactivatedhardwareinterruptcancomeinatanytime,requestingtheattentionoftheCPU.A“CALLFAR”instructioncannotbemasked(disabled),but“INTnn”belongingtoexternallyactivatedhardwareinterruptscanbemasked.A“CALLFAR”instructionautomaticallysavesonlyCS:IPofthenextinstructiononthestack,while“INTnn”savesFR(flagregister)inadditiontoCS:IPofthenextinstruction.Attheendofthesubroutinethathasbeencalledbythe“CALLFAR”instruction,theRET(returnFAR)isthelastinstruction,whereasthelastinstructionintheinterruptserviceroutine(ISR)for“INTnn”istheinstructionIRET(interruptreturn).ThedifferenceisthatRETpopsCS,IPoffthestackbuttheIRETpopsofftheFR(flagregister)inadditiontoCSandIP.1.系统功能调用(MicrosoftDOS)

系统功能调用是微机的磁盘操作系统DOS为用户提供的一组例行子程序,因而又称为DOS系统功能调用。这些子程序可分为以下四个主要方面:(1)磁盘的读/写及控制管理。(2)内存管理。(3)基本输入/输出管理(如键盘、打印机、显示器 等)。(4)其他管理(如时间、日期等)。

为了使用方便,系统已将所有子程序按顺序编号,称为调用号。其调用号为0~75H,如表5.4所示。表中只列出了基本输入/输出管理中部分键盘和显示器DOS功能调用。对于所有的功能调用,使用时一般需要经过以下三个步骤:(1)子程序的入口参数送相应的寄存器。(2)子程序编号送AH。(3)发出中断请求:INT21H(系统功能调用指令).表5.4键盘和显示器的DOS调用调用号功能入口参数出口参数1键入并显示一个字符

键入字符的ASCII码在AL中2显示器显示一个字符DL中置输出字符的ASCII码

5打印机打印一个字符DL中置输出字符的ASCII码

8键盘输入一个字符

键入字符的ASCII码在AL中9显示器显示一个字符串DS:DX置字符串首址,字符串以'$'结束

10(0AH)键入并显示字符串DS:DX置字符串首址,第1单元置允许键入的字符数(含一个回车符)键入的实际字符数在第2单元中,键入的字符从第3单元开始存放11(0BH)检测有无键入

有键入AL=FFH,无键入AL=0例如,显示一个字符串'Goodmorning!'的程序如下:;

MSG DB'Goodmorning!$'; MOV DX,OFFSETMSG;字符串首字符的偏移地址送DX MOV AH,9 ;功能号9送AH INT 21H ;系统功能调用;有的子程序不需要入口参数,这时步骤(1)可以略去。例如:MOV AH,4CH;功能号4CH送AH(返回DOS子程序) INT 21H1)01号功能调用

调用格式: MOV AH,01 INT 21H系统执行该功能时将扫描键盘,等待键入。一旦有键按下,就将键值(相应字符的ASCII码值)读入,先检查是否是Ctrl–Break。若是,则退出命令执行;否则将键值送入AL寄存器,同时将这个字符显示在屏幕上。2)02号功能调用

调用格式: MOV DL,待显示字符的ASCII码 MOV AH,02 INT 21H本调用执行后,显示器显示其ASCII码值放入DL中的字符。3)09号功能调用调用格式: MOV DX,待显示字符串首字符的偏移地址 MOV AH,09 INT 21H

本调用执行后,显示器显示待显示的字符串。调用时,要求DS:DX必须指向内存中一个以“$”作为结束标志的字符串。例如:

例1: DATA SEGMENT BUF DB'HOWDOYOUDO?$' DATA ENDS CODE SEGMENT

MOV AX,DATA MOV DS,AX

MOV DX,OFFSETBUF MOV AH,09 INT 21H

CODE ENDS例2:

.MODELSMALL

.STACK64;

.DATA MESSAGEDB'Thisisatestofthedisplayroutine','$';

.CODEMAIN PROC

FAR MOVAX,@DATA MOVDS,AX

CALLCLEAR;CLEARTHESCREEN

CALLCURSOR;SETCURSORPOSITION

CALLDISPLAY;DISPLAYMESSAGE MOVAH,4CH INT 21H;GOBACKTODOSMAIN ENDP;THISSUBROUTINECLEARSTHESCREENCLEAR PROC MOV AX,0600H;SCROLLSCREENFUNCTION MOV BH,07;NORMALATTRIBUTE MOV CX,0000;SCROLLFROMROW=00,COL=00 MOV DX,184FH;TOROW=18H,COL=4FH INT10H;INVOKEINTERRUPTTOCLEARSCREEN RETCLEAR ENDP;;THISSUBROUTINESETSTHECURSORATTHE;CENTEROFTHESCREENCURSORPROCMOVAH,02;SETCURSORFUNCTIONMOVBH,00;PAGE00MOVDH,12;CENTERROWMOVDL,39;CENTERCOLUMNINT10H;INVOKEINTERRUPTTO;SETCURSORPOSITIONRETCURSORENDP;;THISSUBROUTINEDISPLAYSASTRINGONTHE;SCREENDISPLAYPROC MOVAH,09;DISPLAYFUNCTION MOVDX,OFFSETMESSAGE;DXPOINTSTOOUTPUTBUFFER INT21H;INVOKEINTERRUPT;TODISPLAYSTRING RETDISPLAY ENDP

ENDMAIN4)10(0AH)号功能调用

调用格式:MOV DX,数据区的首偏移地址MOV AH,10INT 21H

该功能调用将从键盘接收的字符串送到内存数据区。要求事先定义一个数据区,数据区内第一个字节指出数据区能容纳的字符个数,不能为零;第二个字节保留,DOS用做填写实际输入的字符个数;从第三个字节开始存放从键盘上接收的字符串。实际输入的字符数少于定义的字节数,数据区内其余字节填零;若多于定义的字节数,则后来输入的字符丢掉,且响铃。调用时,要求DS:DX指向数据区首地址。例如:

例1:

ORG 0010HDATA1 DB 6,?,6DUP(FF);0010H=06,0012Hto;0017H=FF MOV AH,0AH;stringinputoptionofINT21H MOV DX,OFFSET DATA1;loadtheoffset;addressofbuffer INT 21H;invokeinterrupt21H001000110012001300140015001600170600FFFFFFFFFFFF

05CHINACR例2: DATA SEGMENT BUF DB50 ;数据区长度

DB?;DOS填入实际输入的字符个数

DB50DUP(?);定义50个字节存储空间 DATA ENDS CODE SEGMENT

MOV DX,OFFSETBUF MOV AH,10 INT 21H

CODE ENDS

2.常用系统功能调用应用举例例5.5利用DOS系统功能调用实现人机对话。下述程序可以在屏幕上显示一行提示信息,然后接收用户从键盘输入的信息并将其存入内存数据区。

DATA SEGMENTPARS DB100;定义输入缓冲区

DB?

DB100DUP(?)MESG DB'WHATISYOURNAME?' ;要显示的提示信息

DB‘$’;提示信息结束标志 DATA ENDSDISP: MOV DX,OFFSETMESG MOV AH,09;利用9号功能调用显示提示 INT 21HKEYBD: MOV DX,OFFSETPARS MOV AH,10;利用10号功能调用接收键盘输入 INT 21H RETSTART ENDPCODE ENDS ENDBEGIN例5.6编写汇编语言源程序,将键入的4位十进制数(如5,则键入0005)以压缩BCD数形式存入字变量SW中。该程序首先接收键入的4位十进制数,然后拼合为压缩BCD数,存入字变量SW。为了接收键入的4位十进制数,需要在数据段中定义一变量数据区。该数据区应有7个字节,其中第1字节定义为5,即可接收5个字符,第2字节预留给10号功能调用装载实际键入的字符数,第3字节到第7字节预留给10号功能调用装载实际键入的字符,即4字节十进制数的ASCII码和1字节回车的ASCII码。程序如下:

DATA SEGMENT

BUF DB5,0,5DUP(?) SW DW?DATA ENDSCODE SEGMENTBEGIN PROCFAR

ASSUMECS:CODE,DS:DATASTART: PUSH DS SUB AX,AX PUSHAX MOV AX,DATA MOV DS,AX

MOVDX,OFFSETBUF;10号功能调用,;键入4位十进制数 MOV AH,10 INT 21H MOV AX,WORD

温馨提示

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

评论

0/150

提交评论