汇编语言程序设计第8章.ppt

上传人:小飞机 文档编号:6388972 上传时间:2023-10-26 格式:PPT 页数:91 大小:551KB
返回 下载 相关 举报
汇编语言程序设计第8章.ppt_第1页
第1页 / 共91页
汇编语言程序设计第8章.ppt_第2页
第2页 / 共91页
汇编语言程序设计第8章.ppt_第3页
第3页 / 共91页
汇编语言程序设计第8章.ppt_第4页
第4页 / 共91页
汇编语言程序设计第8章.ppt_第5页
第5页 / 共91页
点击查看更多>>
资源描述

《汇编语言程序设计第8章.ppt》由会员分享,可在线阅读,更多相关《汇编语言程序设计第8章.ppt(91页珍藏版)》请在三一办公上搜索。

1、第8章 高级汇编技术,8.1 宏汇编 8.2 重复汇编和条件汇编8.3 汇编语言与高级语言的混合编程,8.1 宏汇编,说明:宏名必须是惟一的,它代表着所定义的宏体的内容,在其后面的源程序中,可通过该名字来调用宏。形式参数表是用逗号(或空格,或制表符)分隔的一个或多个形式参数。它是可选项。选用了形式参数时,所定义的宏称为带参数的宏。当调用宏时,需用对应的实际参数去取代,以实现向宏中传递信息。,宏体可以是汇编语言所允许的任意指令和伪指令语句序列,它决定了宏的功能。在宏体中还可以定义或调用另一个宏,这就是宏嵌套。宏一经定义,就像为指令系统增加了新的指令一样,在程序中就可像指令一样通过宏名对它进行任意

2、次的调用,故又称为宏指令或宏调用。要注意的是,宏定义必须放在第一条调用它的指令之前,一般都将它放在程序的开头。,2宏的调用与展开(1)在汇编语言源程序中,为了使在源程序中不重复书写需要多次使用的程序段,可以用一条宏指令来代替,由汇编程序在汇编时产生所需要的代码。例如,为了实现ASCII码与BCD码之间的相互转换,往往需要把AL中的内容左移4位或右移4位,可以用80 x86的指令来实现。若要左移4位,可用:MOV CL,4 SAL AL,CL,若要多次使用,就可以用一条宏指令来代替,宏定义是:SHIFT MACRO MOV CL,4 SAL AL,CL ENDM 这样,以后凡要使AL中的内容左移

3、4位,就可以用这条宏指令SHIFT来代替。,宏定义中,SHTFT是宏指令名,MACRO是宏定义的定义符,ENDM是宏定义的结束符,这两者必须成对出现。宏汇编一般由可执行的指令语句和管理语句(即由伪指令构成的语句)所构成。经宏定义后,就可以引用宏指令,这称作宏调用。宏汇编程序遇到这样的调用时,就用对应的宏体来代替这条宏指令,以产生目的代码,这称作宏展开。,(2)宏定义不但能使源程序的书写简洁,而且由于宏指令具有接收参量的能力,所以功能就更灵活。例如,上述的宏指令只能使AL中的内容左移4位。若每次使用时,要移位的次数不同,或要使不同的寄存器移位,就不方便了。但是,若在宏定义中引入参量,就可以满足上

4、述要求。,例8-1 定义满足不同移位次数要求的宏。SHIFT MACRO X MOV CL,X SAL CL,CL ENDM其中,X是一个形式参量(此处用来代表移位次数)。在调用时可把实际要求的移位次数作为实在参量代入。如 SHIFT 4就可以用实在参量4代替在宏定义体中出现的形式参量X,从而实现左移4位的功能。,又如:SHIFT 6就可以左移6次。这样,就可以由调用时的实在参数来规定任意的移位次数。,例8-2 定义满足使用不同寄存器实现移位要求的宏,可再引入一个形式参量Y。SHIFT MACRO X,Y MOV CL,X SAL Y,CL ENDM用形式参量Y来代替需要移位的寄存器。只要在调

5、用时,把要移位的寄存器作为实在参量代入,就可以对任一个寄存器实现指定的左移次数。SHIFT 4,AL SHIFT 4,BX SHIFT 6,DI,在汇编这些宏指令时,分别产生以下指令语句,宏汇编程序在每一条由宏展开产生的指令前冠以加号“+”:+MOV CL,4+SAL AL,CL+MOV CL,4+SAL BX,CL+MOV CL,6+SAL DI,CL 第一条宏指令使AL左移4位;第二条宏指令使16位寄存器BX左移4位;第三条宏指令使DI左移6位。,(3)形式参量不仅可以出现在操作数部分,也可以出现在操作码部分。例8-3 用宏指令定义操作码。SHIFT MACRO X,Y,Z MOV CL,

6、X S&Z Y,CL ENDM 其中第三个形式参量Z代替操作码中的一部分。若在宏定义体中的形式参量没有适当的分隔符,则不被看作为形式参量,调用时也不被实在参量所代替。,例如,上例中的操作码部分S&Z中,若Z与S之间没有分隔,则此处的Z就不被看作形式参量。要定义它为形式参量,必须在其前面加上符号&。所以S&Z中Z就被看作是形式参量。若有以下调用:SHIFT 4,AL,AL SHIFT 6,BX,AR SHIFT 8,SI,HR,在汇编这些宏指令时,分别产生以下指令语句。+MOV CL,4+SAL AL,CL+MOV CL,6+SAR BX,CL+MOV CL,8+SHR SI,CL 这里的SHI

7、FT宏指令可以对任一个寄存器进行任意的移位操作(算术左移、算术右移、逻辑右移、可移任意指定的位数)。,宏指令名是一个宏定义调用的依据,也是不同宏定义相互区分的标志,是必须要有的。对于宏指令名的规定与对标识符的规定是一致的。宏定义中的形式参量表是任选的,可以没有形式参量,也可以有若干形式参量。若有一个以上的形式参量时,它们之间必须用逗号分隔。对形式参量的规定与对标识符的规定是一致的。形式参量的个数没有限制,只要一行限制在152个字符以内就行。在调用时的实在参量多于1个时,也要用逗号分隔,它们与形式参量在顺序上相对应。但IBM宏汇编并不要求它们在数量上必须一致。若调用时的实在参量多于形式参量,则多

8、余的部分被忽略;若实在参量少于形式参量,则多余的形式参量变为NULL(空)。,2)PURGE一个宏指令名,可以用伪指令PURGE来取消,然后就可以重新定义。格式:PURGE 宏指令名,功能:取消多个宏定义。,例8-4 X=0 REPT 10 X=X+1 DB X ENDM实现的功能是把1到10分配给10个连续的内存单元。,例8-5 IRP X,DB X ENDM 因为参数表中的参数个数为10,故指令体部分重复执行10次。例8-4中的指令体部分只有一条伪指令DB X,其中X为形式参量。在第一次执行时用参数表中的第一个参数1代替形式参量,就为DB 1;第二次执行时,用参数表中的第二个参数2代替形式

9、参量,就为DB 2;所以例8-4也是把1到10分配给10个连续的内存单元。,例8-6 IRPC X,DB X ENDM实现的功能是:把字符A到F分配给内存中的6个连续单元。以上MACRO、REPT、IRP和IRPC 4个宏定义的伪指令都必须以伪指令ENDM作为它的结束符。,有两点需要特别指出:宏定义也可以像程序设计语言中的标准函数一样,构成一个标准函数库,供其他源程序使用。以文件的形式组织若干个宏定义即形成宏程序库。程序设计中使用了宏程序库中的宏定义时,在源程序中应使用INCLUDE伪指令。宏汇编程序在汇编源程序时,当遇到该伪指令,就把INCLUDE伪指令所包含的宏程序库中的文件扫描一遍,如同

10、在程序中使用自己定义的宏一样,在后面的程序中就可以对宏库中的宏定义直接进行宏调用了。,与子程序一样,宏定义也可以嵌套。宏定义的嵌套有两种方式:宏定义嵌套和宏定义内嵌套宏调用。在一个宏定义中包含了另一个宏定义,则称为宏定义嵌套;在一个宏定义的宏体内有宏调用,则称为宏定义内嵌套宏调用。在宏定义内嵌套宏调用中,被调用的宏指令必须是已定义的。宏定义嵌套常用于产生一些新的宏定义,而宏定义内嵌套宏调用则可以使宏定义简化,功能单一,便于通过组合的方法实现一个功能较为复杂的宏定义。,8.1.3 LOCAL伪指令 如果宏定义中含有变量名或标号,且在同一源程序中又多次被宏调用,那么宏汇编程序在宏展开时,产生多个相

11、同的变量名或标号,这就不能满足变量名和标号在同一程序中必须惟一的要求,从而产生汇编出错,即产生“ERROR A2005:SYMBOL IS MULTIDEFINED”的错误。为达到在宏定义中使用变量名和标号,又能避免这个错误的目的,可在宏定义中使用局部符号伪指令LOCAL对变量名或标号进行说明。,格式:LOCAL 功能:对在符号表中的每个符号,在汇编时每扩展一次便建立一个“?XXXX”惟一的符号,保证汇编时生成名字的惟一性。说明:(1)符号表是在宏定义中定义的变量名和标号,多个符号之间用逗号分隔。(2)LOCAL伪指令指定的变量名和标号自动生成格式为“?XXXX”,符号的后四位顺序使用0000

12、FFFF的十六进制数字。,8.1.4 宏和过程的比较 宏和过程都可用来简化源程序,并可使程序多次对它们进行调用,从而使程序结构简洁清晰,符合结构化程序设计风格。因此,对于那些需重复使用的程序模块,既可用过程也可用宏来实现。,宏和过程的主要区别在于:(1)宏操作可以直接传递和接收参数,它不需通过栈等其他媒介来进行,因此编程比较容易。而过程不能直接带有参数,当过程之间需要传递参数时,必须通过栈、寄存器或存储器来进行,所以相对于宏而言,它的编程要复杂一些。,(2)宏调用只能简化源程序的书写,缩短源程序长度,它并没有缩短目标代码的长度,汇编程序处理宏指令时,是把宏体插入到宏调用处,所以目标程序占用内存

13、空间并不因宏操作而减少。而过程(子程序)调用却能缩短目标程序的长度,因为过程在源程序的目标代码中只有一段,无论主程序调用多少次,除了增加CALL和RET指令的代码外,并不增加子程序段代码。(3)引入宏操作并不会在执行目标代码时增加额外的时间开销。相反,过程调用由于需要保护和恢复现场及断点,因而有额外的时间开销,会延长目标程序的执行时间。,若在一个源程序中多次调用一段程序,则可用子程序,也可以用宏指令来简化源程序。用子程序的方法,汇编后产生的目标代码少,即目标程序占用的内存空间少,节约内存空间。但是,子程序在执行时,每调用一次都要先保护断点,通常在程序中还要保护现场。同样,在返回时,先要恢复现场

14、,然后恢复断点(返回)。这些操作都额外增加了时间,因而执行时间长,速度慢。而宏指令恰好相反,它的目标程序长,占用的内存单元多,但在执行时不需要保护断点、现场以及恢复、返回等这些额外操作,因而执行时间短,速度快。,所以,当要代替的程序段较短,速度是主要矛盾时,通常用宏指令。而当要代替的程序段较长,额外操作所附加的时间不明显,节省存储空间是主要矛盾时,通常用子程序。宏指令是机器的指令系统中没有的,但又可以作为一条指令使用。所以,从形式上看,宏指令扩充了机器的指令系统。,8.2 重复汇编和条件汇编,8.2.1 重复汇编 在汇编程序设计中,经常要连续地重复相同的或几乎完全相同的代码序列,这时可以使用重

15、复伪指令。1重复伪指令 宏汇编语言提供的重复伪指令包括REPT、IRP、IRPC,其格式、功能及使用说明在8.1.2节中已讲述,这里不再赘述。,2重复伪指令应用举例 例8-7 使用不同重复伪指令定义10个数据,使其内容分别为0,1,9。第一种方法,使用REPT伪指令:COUNT0 REPT 10 DB COUNT COUNTCOUNT+1 ENDM,第二种方法,使用IRP伪指令:IRP X,DB X ENDM第三种方法,使用IRPC伪指令:IRPC X 0123456789 DB X ENDM,以上三种方法具有同样的功能,汇编后产生的代码如下:+DB 0+DB 1+DB 2+DB 3+DB 4

16、+DB 5+DB 6+DB 7+DB 8+DB 9,例8-8 下面两条重复伪指令具有相同的功能。(1)IRP指令:IRP REG,POP REG ENDM,(2)IRPC指令:IRPC R ABCD POP RX ENDM汇编后它们产生的代码如下:+POP AX+POP BX+POP CX+POP DX,8.2.2 条件汇编 条件汇编伪指令可使汇编程序根据某种条件对某部分源程序有选择地进行汇编,在形式上和高级语言中的条件语句类似,但实质不同。条件汇编语句是一种说明性语句,其功能由汇编系统实现;而一般高级语言的条件语句是执行性语句,其功能由目标程序实现。条件汇编语句通常在宏定义中使用,使得宏定义

17、的适用范围更广。一般情况下,使用条件汇编语句可使一个源文件产生几个不同的源程序,它们可有不同的功能。,格式:IF 条件 语句序列1 ELSE 语句序列2 ENDIF 功能:当条件为真(满足)时执行汇编语句序列1,否则执行汇编语句序列2。,说明:“条件”为IF伪指令说明符的一部分,ELSE伪指令及其后面的语句序列2是可选择部分,表示条件为假(不满足)时的情况。如果属于非完全分支的判断,就不用这部分。整个条件汇编最后必须用ENDIF伪指令来结束。语句序列1和语句序列2中的语句是任意的,也可为条件汇编语句。以下5组条件汇编开始语句均可选用ELSE语句,以便汇编条件为假时执行语句序列2,但一个IF语句

18、只能有一个ELSE与之对应。,1)是0否条件语句 语句有:IF和IFE。IF语句。格式:IF 表达式 功能:表达式值非0,则条件为真,执行汇编语句序列1。IFE语句。格式:IFE 表达式 功能:表达式值为0,则条件为真,执行汇编语句序列1。,2)扫描1否条件语句 语句有:IF1和IF2。IF1语句。格式:IF1 功能:汇编处于第一次扫描时条件为真。IF2语句。格式:IF2 功能:汇编处于第二次扫描时条件为真。,3)符号有定义否条件语句语句有:IFDEF和IFNDEF。IFDEF语句。格式:IFDEF 符号 功能:符号已被定义或已由EXTRN伪指令说明,则条件为真。IFNDEF语句。格式:IFN

19、DEF 符号 功能:符号未被定义或未由EXTRN伪指令说明,则条件为真。,4)空否条件语句语句有:IFB和IFNB。IFB语句。格式:IFB 功能:参数为空格,则条件为真。尖括号不能省略。IFNB语句格式:IFNB 功能:参数不为空格,则条件为真。尖括号不能省略。,5)字符串比较条件语句语句有:IFIDN和IFDEF。IFIDN语句。格式:IFIDN,功能:字符串1与字符串2相同,则条件为真。,IFDIF语句 格式:IFDIF,功能:字符串1与字符串2不相同,则条件为真。说明:这两条语句只能在宏定义中使用,检查传送给两个参数的实参是否相同。例8-9 将输入及输出字符的DOS功能调用放在一个宏定

20、义中,通过判断参数为0还是非0值来选择是执行汇编输入还是输出的DOS功能。,所编制的程序描述如下,其中含有条件汇编的语句。INOUTMACRO X IF X MOV AH,2 INT 21H;输出DL中的字符 ELSE MOV AH,1 INT 21H;输入一个字符到AL ENDIF ENDM,当宏调用为INOUT 0时,表明传递给参数X的值为0,此时IF X的条件为假,因此汇编程序只汇编ELSE与ENDIF之间的语句,这样,对该宏调用来说,实际上是执行下面的两条指令:MOV AH,1 INT 21H而当宏调用为INOUT 1时,实际上是执行这样两条指令:MOV AH,2 INT 21H,8.

21、3 汇编语言与高级语言的混合编程,8.3.1 调用协议 汇编程序和汇编语言常常以在线汇编语言代码的形式,通过过程同高级语言,如C/C+、BACIC、PASCAL及FORTRAN一起使用。需要指出的是,这里尽管讲的是使用Microsoft汇编语言过程,但只要提供兼容的调用协议,大多数其他语言也能够使用。在与高级语言接口时,汇编程序使用两种调用协议:一是用于C/C+语言的C语言调用协议,二是用于BASIC、PASCAL和FORTRAN语言的PASCAL语言调用协议。调用协议语言在MODEL语句中或与PROC语句相联系的OPTION指示符中指定。除用这些语句以外还可以用完全段定义指定。,1C语言调用

22、协议 C语言调用协议从右到左压入参数,像它们在参数表里放的那样,带着放在栈上的参数从汇编语言过程返回,返回结果或者放在AX中或者放在DXAX中。在BP、DI、SI、DS、SS和方向标志位被改动之前应使用汇编语言过程保存起来。这些寄存器是高级语言能用到的。图8-1给出了C语言调用协议下近调用和远调用的栈。,图8-1 使用C语言调用协议时的栈内容(a)近程调用;(b)远程调用,对栈内参数的访问由C语言调用协议提供,如例8-10所示。带*号的语句是汇编程序加上的,以保持与C语言调用协议的一致。注意搞清楚BP的内容如何被压入栈中,以及BP是如何被装入SP值以访问由C语言程序放在栈中的参数这两个问题。,

23、例8-10.LISTALL.MODEL SMALL,CSSS PROTO C,A:SWORD,A:SWORD.CODE SSS PROC C,A:SWORD,B:SWORD PUSH BP;保存BP MOV BP,SP;栈地址存入BP MOV AX,A;使用参数A ADD AX,B;使用参数B POP BP;恢复BP RET 00000HSSS ENDP END,根据C语言调用协议编写的汇编语言过程通过指令INVOKE而被调用。INVOKE用来替代标准的CALL指令。INVOKE遵循C语言调用协议,允许汇编语言程序访问C语言程序和函数。INVOKE指令被用来访问例8-10中的过程,例如,INV

24、OKE SSS,20,30实现把30加上20后,结果放入AX中并返回。INVOKE与CALL的不同之处,按照调用协议的要求,INVOKE指令必须将参数从栈中全部移出。INVOKE指令的语法要求过程名后必须跟着全部的参数,参数间用逗号隔开。,2INVOKE指令的使用 用 PUSH把参数压入堆栈,如果不小心把参数个数搞错了,就会使堆栈不平衡,从而使程序从堆栈中取出错误的返回地址,引起不可预料的后果。所以有必要用一条语句来完成自动检验的任务。INVOKE语句是能自动将所有的参数压入栈中,并检测参数个数、类型是否正确,使用 CALL来调用的一个宏指令。INVOKE在汇编程序中调用子程序时,其参数的传递

25、是通过堆栈来进行的。例如,MessageBox()函数在USER32.INC文件中是这样声明的:MESSAGEBOX(HWND HWND,LPCTSTR LPTEXT,LPCTSTR LPCAPTION,UINT UTYPE),,在汇编程序中可这样调用它:PUSH UTYPE PUSH LPCAPTION PUSH LPTEXT PUSH HWND CALL MessageBox PUSH为汇编语言中的进栈指令。上面语句的原理是先将函数所需要的参数,压入到堆栈中去,然后再用CALL指令来调用该函数。,需要注意的是,在上述的参数进栈过程中,是从左到右依次压入的,即最右面的参数是最后一个进堆栈,采

26、用的是PASCAL规则。引入INVOKE语句后,就可自动的将所调用子程序中的参数压入堆栈中,而无须编程者用手工压入。所以上面的代码就可以变为 INVOKE MessageBox,NULL,addr szText,addr szCaption,MB_OK。addr是用来把变量参数的地址传递给被调用的函数(注意,是所指变量在内存中的地址,而不是变量中的值),它只能在INVOKE语句中使用。,3PASCAL语言调用协议 PASCAL语言调用协议用于BASIC、PASCAL和FORTRAN语言,在WINDOWS中,它也被用于访问WINDOWS库文件(WINH.LIB)中的函数。PASCAL语言调用协议

27、与C语言调用协议的差异在于:参数是自左至右压入栈中。如果用在汇编语言过程中时,PASCAL语言调用协议也需要保存寄存器SI、DI、DS和SS的内容。方向标志位在登录时要被清零,并以清除状态被返回。和在C语言调用协议中一样,INVOKE语句也用于由汇编语言进出高级语言过程。,这一点在汇编语言同WINDOWS一起使用时格外重要,以INVOKE MessageBeep,-1为例,如果WINH.LIB库文件已被程序装载,则该指令使扬声器发出“嘀”的一声。其他参数也可与MessageBeep一起使用,从而由WINDOWS发出各种失败提示音。在C语言程序中,通过在C语言程序的开头使用指令#INCLUDE,

28、就可以访问WINDOWS应用程序接口(API)。,图8-2 使用PASCAL语言调用协议时栈内容,图8-2给出了从PASCAL中调用函数时的栈,注意:所有这些语言调用的函数都被认为是远程调用,BP给出了存储参数的栈的地址。最右边的参数的地址为BP+6,这一点与C语言调用协议正好相反。同C语言调用协议一样,隐蔽的指令将BP压入栈,并将SP写入BP。,4数据类型,表8-1 各种数据类型的比较,8.3.2 与C语言的接口 例8-11 本例给出了一个被C语言程序调用的过程,该过程使用MODEL语句指示内存模型(本例为小模型)和相应的调用协议语言(C语言)。PROTO语句把本过程作为外部函数声明,并指定

29、了全部与本过程相关的参数的大小和名称。本过程被作为一个近程调用.MODEL SMALL,CX1 PROTO C,l:SWORD,F:SWORD.CODE,X1 PROC C,l:SWORD,LSWORD FILDPI;取出 FADD ST,ST(0);计算2pi MOV AX,1;取1 MOV TEMP,AX FILD TEMP;取l FMUL;计算2pil MOV AX,F;取F MOV TEMP,AX FILD TEMP;取F FMUL;计算2pilf FISTP TEMP;保存结果,MOV AX,TEMP;取结果用以返回C RETX1 ENDP TEMP DW?;暂存区 END,本过程使

30、用数值协处理器计算电抗值,使用公式X1=2lF。其中,参数F和l从C语言程序中传送到汇编语言过程中,返回值(X1)作为一个字长的整型变量由AX传回C语言程序。通过BP+4和BP+6给出的地址,可以从栈中取出l和F的数据。本例中的MOV AX,l指令,若转换为代码应为MOV AX,BP+4,通过该指令可从栈中取出l值。,例8-12 本例给出了主模块的C语言调用顺序,该程序顺序打印出电感系数为4H,频率为1000 Hz的电抗值。注意:本程序中的计算结果被变换为整型。#include extern int xl(int l,int f);void main()printf(The inductive

31、 reactance of 4 H at 1000 Hz isdn,xl(4,1000);,8.3.3 与PASCAL语言的接口 1有关的PASCAL语句和调用约定 PASCAL语言没有提供CALL调用语句。PASCAL主程序对汇编语言子程序的调用是通过外部过程和外部函数调用的形式来实现的。为了保证调用的正确实施,PASCAL主程序和被调用的汇编语言子程序都要遵从一定的调用约定。PASCAL语言中的过程和函数有所不同。,1)过程方式 在PASCAL程序中,对要调用的汇编语言过程必须预先采用PROCEDURE说明语句加以定义说明。PROCEDURE语句的格式为:PROCEDURE过程名(参数表)

32、:过程属性;这样,PROCEDURE语句将向PASCAL编译程序提供如下信息:(1)被调用的过程名;(2)此过程是内部过程还是外部过程;(3)过程的参数名和类型;(4)是“数值参数”还是“引用参数”。,由于汇编语言子程序是单独编写和汇编的,它相对PASCAL主程序而言总是外部的。所以,其“过程属性”为EXTERN。并且,过程名必须在汇编语言程序中用PUBLIC伪指令加以说明。第(3)项的过程参数名和类型是符合PASCAL要求的变量标识符和数据类型。在进行PASCAL过程调用时,过程参数也是通过栈来进行传递的。第(4)项的“数值参数”和“引用参数”涉及到是传递参数变量值,还是传递参数变量地址的问

33、题。当一个变量是数值参数时,主程序把此变量的值入栈,即传递给被调用过程;否则,主程序把此变量的地址入栈。作为引用参数的变量,在PROCEDURE语句中须用VAR或VARS来加以说明。两者的区别在于:对由VAR说明的参数,主程序须将其变量地址的偏移量入栈;而对由VARS说明的参数,除变量地址的偏移量外,主程序还要将此变量地址的段地址入栈。语句:,PROCEDURE ADDP(A,B:INTEGER;VAR C:INTEGER):EXTERN;,定义了一个有3个参数的外部过程ADDP。其中,变量A和B是整型数值参数,而变量C是整型引用参数;一旦汇编语言过程在PASCAL主程序中经由PROCEDUR

34、E语句定义说明后,PASCAL主程序就可以采用相应的过程调用语句来调用此汇编语言过程了,过程调用语句的格式为 过程名(参数表)对上面的ADDP过程,其相应的过程调用语句为 ADDP(A,B,C)其中,A,B,C是PASCAL主程序中的整型变量。,在被调用的汇编语言子程序中,PASCAL对过程的要求是:(1)由于寄存器SP不能用于一般的寻址方式,通常用BP来存取传递的调用参数。所以,在过程程序开始时要先把BP的原有内容入栈保存,并在返回PASCAL主程序之前恢复内容。另外,若要在子程序中改变DS和SS等寄存器的内容,也须加以保存和恢复。(2)由于是外部过程,在返回PASCAL主程序时应采用长返回

35、指令,即进行段间返回。(3)在返回时,应取消栈参数,即主程序传递给此过程的所有调用参数。,下面是用汇编语言编写的ADDP过程程序,在程序中,PUBLIC指令将过程名ADDP存放。CODE SEGMENT ASSUME CSCODE ADDP PROC FAR PUBLIC ADDP PUSH BP MOV BP,SP PUSH AX,PUSH BX MOV AX,BP+10 ADD AX,BP+8 MOV BXBP+6 MOV BX,AX POP BX POP AX POP BP RET 6 ADDP ENDP,过程的FAR属性使得后面的RET指令成为长返回指令。RET指令中的整数用于消去栈参

36、数,它在返回后将自动加入到SP寄存器中。程序的“RET 6”指令执行前后栈内容的变化如图8-3所示。当ADDP过程的C变量为VARS引用参数时,相应的汇编语言程序有所不同。由于C的段地址,A和B的地址由BP+10和BP+8变为BP+12和BP+10。同时,“RET 6”变为“RET 8”。除此之外,由于C变量不是当前DS寄存器所指数据段中的变量,对它的存取方式也与前不同,如图8-4所示。,图8-3 栈变化,图8-4 C变量为VARS引用参数时的堆栈结构,CODE SEGMENT ASSUME CSCODE ADDP PROC FAR PUBLIC ADDP PUSH BP MOV BP,SP

37、PUSH AX PUSH BX PUSH ES MOV AX,BP+12,ADD AX,BP+10 LES BX,BP+6 MOV ESBX,AX POP ES POP BX POP AX POP BP RET 8 ADDP ENDP CODE ENDS END,2)函数方式 函数方式同过程方式很相似。在PASCAL程序中,对要调用的汇编函数也必须预先加以说明。不过,此时采用的是FUNCTION说明语句,而不是PROCEDURE说明语句。FUNCTION语句的格式为 FUNCTION 函数名(参数表):函数类型;函数属性;在FUNCTION语句中,除增加了一个“函数类型”外,其余同PROCED

38、URE语句一样。“函数类型”符合PASCAL要求的数据类型的语句。如:FUNCTION ADDF(A,B:INTEGER):INTEGER:EXTERN;说明定义了一个名为ADDF的外部整型函数。,PASCAL对汇编函数的要求,除在程序完成后必须返回函数值外,其余同过程完全一样。一般来说,函数可通过AL、AX、ESBX或调用者提供的缓冲区来返回其值。具体使用时应根据函数的类型和语言编译程序版本的要求来选择。下面是ADDF函数的汇编程序。通过和本节给出的第一个程序比较可知,ADDP和ADDF的功能是一样的,都是求A、B之和,不同的是,ADDF函数是通过AX直接返回结果值,而ADDP过程则是通过设

39、置的VAR参数C来返回的。,CODE SEGMENT ASSUMEE CS:CODE ADDF PROC FAR PUBLIC ADDF PUSH BP MOV BP,SP PUSH AX MOV AX,BP+8 ADD AX,BP+6 POP BP RET 4 ADDF ENDP CODE ENDS END,2连接方法 PASCAL主程序和汇编语言子程序通过连接程序LINK连为一体,形成可执行文件。连接的具体过程如下:(1)汇编源程序ADDP.ASM,得到相应的目标文件ADDP.OBJ:CMASM ADDP;(2)汇编源程序ADDF.ASM,得到相应的目标文件ADDF.OBJ:C MASM

40、ADDF;,(3)编译源程序MAIN.PAS,得到相应的目标文件MAIN.OBJ:C PAS1 MAIN;C PAS2(4)连接目标模块ADDF.OBJ、ADDP.OBJ和MAIN.OBJ,生成可执行文件MAIN.EXE:C LINK MAIN+ADDP+ADDF;执行可执行文件MAIN.EXE将得到如下结果:CMAIN 3 3,下面是PASCAL主程序MAIN.PAS。PROGRAM MAIN(OUTPUT);PROCEDURE ADDP(A,B:INTEGER;VAR C:INTEGER);EXTERN;FUNCTION ADDF(A,B:INTEGER):INTEGER;EXTERN;V

41、AR A,B,C:INTEGER;BEGIN A=1;B=2;ADDP(A,B,C);A=ADDF(A,B);WRITE(A,C)END.MAIN,习 题 八,8.1 在代码段中,开始的一段程序有通用性,试将此段程序定义为一条宏指令。8.2 定义条宏指令,它可以实现任一数据块的传送(假设无重叠),只要给出源和目的数据块的首地址以及数据块的长度即可。如果条宏指令既可以从数据块的首地址又可从其末地址开始传送这个数据块,应如何定义这条宏指令?,8.3 编写实现下述功能的宏指令。(1)清屏。(2)设置光标,要求光标的行、列号用形式参数表示;(3)字符串的逆序存放,要求原字符串及逆序串的首地址用形式参数表示。8.4 试用调用宏指令的方法计算Y(A2+B2),要求计算X2用累加的方法实现,并用宏指令表示。,8.5 STORE宏指令定义如下:STORE MACRO X,N MOV X+I,I II+1 IF I-N STORE X,N ENDIF ENDM有以下宏调用:I0 STORE TAB,6试对其进行宏扩展。,8.6 试编写一段程序完成以下功能:若给定名为X的字符串长度大于5时,对DEC CX指令汇编4次。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号