汇编语言高级编程技巧和程序设计_第1页
汇编语言高级编程技巧和程序设计_第2页
汇编语言高级编程技巧和程序设计_第3页
汇编语言高级编程技巧和程序设计_第4页
汇编语言高级编程技巧和程序设计_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

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

文档简介

1、8.1 模块化程序设计8.2 汇编语言程序与高级语言程序的连接8.3 使用DOS EXEC功能执行程序8.4 TSR程序设计软件工程开发包括以下步骤:系统分析; 系统设计; 细化各模块的功能、确定模块间的关系及通信方 法; 完成各模块的程序编码及模块调试; 连接多个模块组成大系统; 调试大系统; 系统维护。8.1 模块化程序设计 主模块模块B模块C模块A模块D模块C模块E图8-1 模块的层次结构8.1.1 模块通信1.外部引用与全局符号说明例实现PRICEQTYTOTAL的功能。要求由两个模块实现,其中主模块给出数据,子模块实现两数相乘。主模块DATASEGMENTPRICE DW 60QTY

2、 DW 80TOTAL DD ?DATAENDSCODESEGMENT ASSUME CS:CODE,DS:DATAMAINPROC FARMOV AX,DATAMOV DS,AX CALL FAR PTR SUBM MOV AX,4C00H INT 21HMAINENDPCODEENDS END MAIN子模块CODE SEGMENTSUBM PROC FAR ASSUME CS:CODE MOV AX,PRICE MUL QTY MOV WORD PTR TOTAL,AX MOV WORD PTR TOTAL+2,DX RETSUBM ENDPCODE ENDS END(1)外部引用伪指令

3、EXTRN格式:EXTRN 名字:类型,.注意:EXTRN伪指令应该出现在引用该名字之前,一般放在程序的开头。(2)全局符号说明伪指令PUBLIC格式:PUBLIC 名字,.例8.1 实现PRICEQTYTOTAL的功能。其中数据定义和乘法实现分别在两个模块中。程序见程序。 程序8.1a 主模块EXTRN SUBM:FARPUBLIC PRICE,QTY,TOTALstacksg segment stack stk dw 32 dup(s)stacksg endsdata segmentPRICE DW 60QTY DW 80TOTAL DD ?data endscode segmentmai

4、n proc far assume cs:code,ds:data mov ax,data mov ds,ax CALL FAR PTR SUBM MOV AX,4C00H INT 21Hmain endpcode ends end main返回程序8.1b 子模块EXTRN PRICE:WORD,QTY:WORD,TOTAL:DWORDPUBLIC SUBMCODE SEGMENTSUBM PROC FAR ASSUME CS:CODE MOV AX,PRICE MUL QTY MOV word ptr TOTAL,AX MOV word ptr TOTAL+2,DX RETSUBM END

5、PCODE ENDS END返回2. 使用公用数据段实现过程通信COMMON功能:告诉连接程序把多个同名数据段在连接时重叠形成一个段,产生段覆盖。说明:具有COMMON组合类型的最长段决定了公共段的长度,重叠部分的内容取决于连接时最后一个公共段的内容。 例8.2 实现例的功能,但使用公用数据段实现过程通信,见程序。程序(主程序):EXTRN SUBM:FARSTACKSG SEGMENT STACK STK DW 32 DUP(S)STACKSG ENDSDATA SEGMENT COMMONPRICE DW 60QTY DW 80TOTAL DD ?DATA ENDSCODE SEGMENT

6、MAIN PROC FAR ASSUME CS:CODE,DS:DATA MOV AX,DATA MOV DS,AX CALL FAR PTR SUBM MOV AX,4C00H INT 21HMAIN ENDPCODE ENDS END MAIN程序(子程序)PUBLIC SUBMDATA SEGMENT COMMONPRICE DW 80QTY DW 60TOTAL DD ?REM DB123 ;局部变量DATA ENDSCODE SEGMENT SUBM PROC FAR ASSUME CS:CODE,DS:DATA PUSH DS PUSH AX PUSH DX MOV AX,DATA

7、 MOV DS,AX MOV AX,PRICE MUL QTY MOV WORD PTR TOTAL,AX MOV WORD PTR TOTAL+2,DX POP DX POP AX POP DS RETSUBM ENDPCODE ENDS END 返回3.使用寄存器或堆栈实现过程通信 在模块化程序设计中,也可以使用寄存器或堆栈传递参数或参数地址,从而实现过程通信。例如,通过AX、DX寄存器把PRICE和QTY的值传递给子程序实现过程通信。EXTRN SUBM:FARPUBLIC TOTALdata segmentPRICE DW 60QTY DW 80TOTAL DD ?data ends

8、MOV AX,PRICE MOV DX,QTY CALL FAR PTR SUBM end main可以把程序改为:EXTRN TOTAL:DWORDPUBLIC SUBM MUL DX MOV word ptr TOTAL,AX MOV word ptr TOTAL+2,DX END8.1.2 模块连接一个程序可以由若干个模块组成,一个模块又可以包含多个段,这些模块经过分别调试后,最终要组装到一起,形成一个大系统。一、多模块程序设计上机步骤以程序的和两个独立模块为例,讨论多模块程序设计上机步骤。 对各模块分别处理以保证其功能的正确性 构造主模块 例如把第步所得到的修改成主模块形式。键入命令:

9、edit prices.asm 如程序所示。 构造子模块 例如把第步所得到的修改成子程序的形式。键入命令:edit prices.asm 如程序所示。 对所有模块分别汇编,生成各自的.obj文件键入命令:masm pricem 生成等文件键入命令:masm prices 生成等文件若汇编过程出现错误,应修改源程序,直到汇编通过。 连接与本系统相关的所有.obj文件键入命令:link pricem+prices,price;于是生成了文件。 调试及运行程序用DEBUG调试文件及运行的过程同第4章。二、连接对程序设计的要求段定义伪指令的完整格式:段名 SEGMENT 定位类型组合类型类别 段名 E

10、NDS其中 中的内容是可选的,各项含义如下:1定位类型确定段的起始边界。BYTE:字节边界,从任意地址开始。WORD:字边界,从偶地址开始。DWORD:双字边界,从可以被4整除的地址开始。PARA(缺省值):节边界,从可以被16整除的地 址开始。PAGE:页边界,从可以被256整除的地址开始。 2类别说明本段归于哪一类。3组合类型说明段之间的关系。可以是: 缺省值 PUBLIC STACK COMMON AT 段基址表达式例:VIDEORAM SEGMENT AT 0B800H三、模块连接举例1使用缺省的组合类型和定位类型程序主模块EXTRN SUBM:FARPUBLIC PRICE,QTY,

11、TOTALdata segmentPRICE DW 60QTY DW 80TOTAL DD ?data endscode segmentmain proc far assume cs:code,ds:data mov ax,data mov ds,ax CALL FAR PTR SUBM MOV AX,4C00H INT 21Hmain endpcode ends end main子模块EXTRN PRICE:WORD,QTY:WORD,TOTAL:DWORDPUBLIC SUBMCODE SEGMENTSUBM PROC FAR ASSUME CS:CODE . MOV AX,PRICE M

12、UL QTY MOV word ptr TOTAL,AX MOV word ptr TOTAL+2,DX. RETSUBM ENDPCODE ENDS END程序连接后生成的.MAP文件主、子模块的code segment效果 Start Stop Length Name Class 00000H 0003FH 00040H STACKSG STK 00040H 00047H 00008H DATA 00050H 0005EH 0000FH CODE 00060H 00072H 00013H CODE Program entry point at 0005:0000主、子模块的CODE段均无任

13、何可选项的.MAP文件2使用PUBLIC组合类型若把程序两个模块的代码段均定义为PUBLIC组合类型且同段名同类别名,例如:CODE SEGMENT PARA PUBLIC CODE 则连接后生成的.MAP文件中只有一个代码段CODE,其总长度为00023H,它是主、子模块代码段长度的总和。 Start Stop Length Name Class00000H 0003FH 00040H STACKSG STK 00040H 00047H 00008H DATA 00050H 00072H 00023H CODE CODEProgram entry point at 0005:00003堆栈段

14、使用STACK组合类型在程序的主、子模块中均增加同段名同类别名且具有STACK组合类型的段,例如:STACKSG SEGMENT STACK STK DW 32 DUP(S)STACKSG ENDS则连接后生成的堆栈段长度为两个模块中的栈长度之和80H,.MAP文件如下: Start Stop LengthName Class 00000H 0007FH 00080H STACKSG STK 00080H 00087H 00008H DATA 00090H 0009EH 0000FH CODE 000A0H 000B2H 00013H CODE Program entry point at 0

15、009:00004数据段使用COMMON组合类型COMMON组合类型的程序示例见程序,其.MAP文件如下所示。其数据段的长度为0BH(具有COMMON组合类型的最长段),产生了段的覆盖。 Start Stop Length Name Class 00000H 0003FH 00040H STACKSG STK 00040H 0004AH 0000BH DATA 00050H 0005EH 0000FH CODE 00060H 00079H 0001AH CODE Program entry point at 0005:0000设新局部数据段名为NEW_DATA,原局部数据段名为OLD_DATA

16、ASSUME DS: NEW_DATAPUSH DS ;保存原局部数据段基址MOV AX,NEW_DATA ;建立新局部数据段寻址MOV DS,AX ;访问NEW_DATA段的数据POP DS ;恢复原局部数据段基址8.1.3 模块组织建议当全部堆栈数据的总长度不超过段长限定时,通常使用STACK组合类型且同段名同类别名定义所有堆栈段,使其连接后生成一个堆栈段,这样使用起来十分方便。但在必须使用多个独立堆栈段的场合,需要注意堆栈的切换,即堆栈段寄存器SS和堆栈指针SP的保存与恢复,此时需要用内存变量保存原值,如程序所示。程序EXTRN PRICE:WORD,QTY:WORD,TOTAL:DWO

17、RDPUBLIC SUBMSTACKSG SEGMENT DW 16 DUP(a)TOP LABEL WORDSTACKSG ENDSCODE SEGMENTSUBM PROC FAR ASSUME CS:CODE,SS:STACKSG mov cs:sav_ss,ss mov cs:sav_sp,sp cli mov ax,stacksg mov ss,ax mov sp,offset top sti push AX PUSH DX MOV AX,PRICE MUL QTY MOV WORD PTR TOTAL,AX MOV WORD PTR TOTAL+2,DX POP DX POP AX

18、 cli mov ss,cs:sav_ss mov sp,cs:sav_sp sti RETsav_ss dw ?sav_sp dw ?SUBM ENDPCODE ENDS END设程序的主模块PRICEM有以下堆栈段定义,把程序与程序连接,则生成图8-6的.MAP文件。 stacksg segment stack stk dw 32 dup(s)stacksg ends Start Stop Length Name Class 00000H 0003FH 00040H STACKSG STK 00040H 00047H 00008H DATA 00050H 0005EH 0000FH COD

19、E 00060H 0007FH 00020H STACKSG 00080H 000B6H 00037H CODE Program entry point at 0005:0000 图8-6 含有多个堆栈段的.MAP文件8.1.4 模块程序设计上机步骤 各个模块独立调试以确保功能的正确性。构造主模块。构造子模块。对第和第步得到的所有模块分别汇编,生成各自的.obj等文件。把第步产生的所有.obj文件连接到一起。运行及调试程序。8.1.5 综合举例 略(见书254页)。8.2.1 C语言程序中直接嵌入汇编代码 1. 内嵌汇编语句格式 格式: asm 内嵌汇编语句的操作数可以是: C程序中的符号 汇

20、编指令操作数可以是结构数据 8.2 汇编语言程序与高级语言程序的连接 2. 转移指令的执行内嵌汇编指令可以使用转移指令和LOOP 循环指令,但是它们只能在函数体内有效,不允许进行段间转移。由于asm 语句中不能给出标号,因而转移指令只能使用C语言程序中GOTO语句使用的标号。 3. 直接嵌入汇编代码的C语言程序示例程序 main() asm mov ah,2; asm mov dl,*; asm int 21h; printf(n The & above is printed in inline Assembly statement); 对于TURBO C,假设源程序、LIB库均在当前TC子目

21、录下,相应的编译连接命令为:1. 编写汇编子程序注意事项 (1)变量和函数的使用 (2)参数传递 (3)汇编语言子程序的返回值 (4)汇编语言子程序中寄存器的使用 8.2.2 在C程序中直接调用汇编子程序 2. 使用C和汇编语言混合编程的编译及连接 有两种方法可以采用: (1)以工程(PROJECT)的方式进行在DOS下,用汇编程序将汇编语言子程序汇编生成相应的目标文件.OBJ。在工程文件(设文件名为)中加入将要编译连接的C语言程序及其调用的汇编子程序目标文件名。对工程文件进行编译连接,生成一个.EXE可执行文件。使用这种方法要注意C语言对大小写敏感的问题,最好关闭大小写敏感开关。 (2)采用

22、命令行的方式进行编译连接3. 混合编程实例 具体实例见教材例(p266)。8.2.3 汇编语言程序调用C函数 在汇编源程序中,对所使用的C函数和变量在其名字均应加下划线。对调用的C函数用EXTRN伪指令进行说明。 对汇编语言中使用的C函数变量用“EXTRN 变量名:size”说明,其中size视数据类型而定,例如int型为2。参数传递有两种:一种是在C程序中定义变量,在汇编源程序中把它说明成EXTRN型;另一种是采用堆栈传递,这时要注意参数压入堆栈的顺序。8.3.1 DOS的内存分配与释放功能简介 8.3 使用DOS EXEC功能执行程序 1分配内存块功能48H调用参数:AH48H BX以节(

23、16字节)为单位的附加内存 块的大小返回参数:调用成功 CF0,AX分配的内存块的段地址; 调用失败 CF1,AX错误码,BX最大可用块的 大小。 2释放已分配的内存块功能49H调用参数:AH49H ES待释放内存块的段地址返回参数:调用成功 CF0,并把0存于该内存块的第二和第三 字节,以表示该块未使用; 调用失败 CF1,AX错误码。 3修改已分配的内存块功能4AH调用参数:AH4AH BX以节为单位新申请内存块的大小 ES待修改内存块的段地址返回参数: 调用成功 CF0; 调用失败 CF1,AX错误码,BX最大可用内存的 大小。 8.3.2 使用DOS EXEC功能加载并执行程序 使用DOS的EXEC功能可以实现加载并执行程序等功能。用EXEC功能执行或加载另一个程序的程序称为父进程,由它执行或加载的另一个程序称为子进程。子进程被装入内存或执行时,父进程一直存于内存中。父进程可以通过多种方法把信息传递给子进程。1. EXEC功能简介DO

温馨提示

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

评论

0/150

提交评论