![第14章模块化程设计_第1页](http://file2.renrendoc.com/fileroot_temp3/2021-11/9/50d15152-f9a3-4420-8ae6-adc5060dc9ee/50d15152-f9a3-4420-8ae6-adc5060dc9ee1.gif)
![第14章模块化程设计_第2页](http://file2.renrendoc.com/fileroot_temp3/2021-11/9/50d15152-f9a3-4420-8ae6-adc5060dc9ee/50d15152-f9a3-4420-8ae6-adc5060dc9ee2.gif)
![第14章模块化程设计_第3页](http://file2.renrendoc.com/fileroot_temp3/2021-11/9/50d15152-f9a3-4420-8ae6-adc5060dc9ee/50d15152-f9a3-4420-8ae6-adc5060dc9ee3.gif)
![第14章模块化程设计_第4页](http://file2.renrendoc.com/fileroot_temp3/2021-11/9/50d15152-f9a3-4420-8ae6-adc5060dc9ee/50d15152-f9a3-4420-8ae6-adc5060dc9ee4.gif)
![第14章模块化程设计_第5页](http://file2.renrendoc.com/fileroot_temp3/2021-11/9/50d15152-f9a3-4420-8ae6-adc5060dc9ee/50d15152-f9a3-4420-8ae6-adc5060dc9ee5.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第第1414章章 模块化程序设计模块化程序设计 第第14章章 模块化程序设计模块化程序设计 14.1 段间调用段间调用 14.2 定义外部标识符伪指令定义外部标识符伪指令 14.3 使用使用extrn和和public的范例的范例 14.4 在指令段使用在指令段使用public 14.5 在数据段使用在数据段使用public 14.6 参数传送参数传送 14.7 c语言与汇编语言的链接语言与汇编语言的链接 第第1414章章 模块化程序设计模块化程序设计 14.1 段段 间间 调调 用用 前面介绍的call 指令都是段内的调用,即在同一个指令段内。段内调用的call指令范围为0000hffffh。
2、一条段内调用指令(call) 的目的码是3个字节长度,例如: e8 2000 (0020) ;十六进制第第1414章章 模块化程序设计模块化程序设计 十六进制e8是段内调用指令(call)机器指令的操作码,其操作是先把当前ip指令指针寄存器的值压入堆栈保存,这个值是call的下一条指令地址;然后,再把被调用的子程序的偏移地址(2000逆序)值送入ip 寄存器,ip0020。微处理器把当前cs的值和ip的值相结合形成物理地址,此地址指向被调用子程序的第1字节。当子程序的执行中,遇到ret指令离开子程序返回时,ret指令会从堆栈中弹出ip的保留值,并把它装入ip,使程序返回到call的下一条指令继
3、续执行,这个过程是段内调用。 第第1414章章 模块化程序设计模块化程序设计 其特点是在子程序调用、返回过程中段寄存器cs不变化,只有指令指针寄存器ip发生变化。主程序与被调用的子程序同在一个段内。 模块化程序设计必然涉及到模块间的调用问题。模块间的调用是通过段间的调用来实现的。若被调用的子程序是在现指令段之外,则称为段间调用。一条段间调用指令(call)的机器指令码共有5个字节。例如: 9a 0002 af04 (04af 0200) ;十六进制第第1414章章 模块化程序设计模块化程序设计 十六进制9a是段间调用指令(call)机器指令的操作码。操作是:首先将cs段寄存器的值压入堆栈,并把
4、被调用子程序所在段的段值(af04逆序)装入cs段寄存器,cs04af;然后把ip指令指针寄存器的值压入堆栈,并将被调用子程序相应的偏移地址(0002逆序)装入ip,ip0200。第第1414章章 模块化程序设计模块化程序设计 这些操作建立了被调用子程序的第一条待执行指令的地址: 十六进制 段 值: cs 04af0 偏移地址: ip + 0200 物理地址: 04cf0第第1414章章 模块化程序设计模块化程序设计 当离开子程序返回时,段间调用的ret指令会从堆栈中依序弹出ip和cs两个寄存器的原值,返回到call的下一条指令。其特点是在子程序调用、返回过程中,段寄存器cs和指令指针寄存器i
5、p均发生变化。主程序与被调用的子程序不在同一个段内。 第第1414章章 模块化程序设计模块化程序设计 14.2 定义外部标识符伪指令定义外部标识符伪指令 当进行模块化程序设计时,首先应考虑的问题是模块间控制的耦合和数据的耦合。控制耦合就是模块在怎样的环境下如何进入又如何退出。数据耦合就是诸模块间如何进行数据通讯。例如,有一个主模块(mainprog)调用一个子模块(subprog),它要用到一个段间调用(call),如图14-1所示。第第1414章章 模块化程序设计模块化程序设计 extrn subprog:farmainprog: call subprog public subprogsub
6、prog: ret图14-1 段间调用第第1414章章 模块化程序设计模块化程序设计 主模块mainprog内的call指令,必须知道子模块subprog是位于本段之外的标号。否则汇编过程中会产生一个错误信息指出subprog是一个未定义的符号。extrn伪指令就是执行此功能的,它告诉汇编程序subprog是一个远程的标号(far label),是定义在另一个模块里的。因为汇编程序无法知道真是如此,所以就产生“空的”目的操作数0000,即先空出;而由链接程序在链接时再填入确定值。例如(参考例14.4主模块程序清单): 0011 9a0000-e 第第1414章章 模块化程序设计模块化程序设计
7、子模块subprog内含有一个public伪指令,它告诉汇编程序和链接程序,其他模块需要知道subprog的地址。当mainprog与subprog都已汇编成目的模块文件后,它们可以下列的方式来链接: link mainprog+subprog run file mainprog.exe: list file nul.map: con libraries .lib:第第1414章章 模块化程序设计模块化程序设计 链接程序将一个目的模块内的extrn匹配上另一个模块内的public,并将插入所有需要的偏移地址,然后把两个目的模块组合成一个可执行的文件。若有不匹配的情况,链接程序会给出错误信息。
8、利用extrn和public这两条伪指令,一个模块可以访问其他模块的标识符(变量或者标号)。如果一个标识符只在这一个模块中定义过,那么它相对这个模块就是一个内部的标识符或局部标识符。如果它没有在这一个模块中定义过,而是在其他一个模块中定义过,那么它相对于该模块就称为外部标识符。 第第1414章章 模块化程序设计模块化程序设计 对于只产生一个单一目标模块的汇编语言程序而言,它所访问的所有标识符必须是局部(内部)定义的,否则就会产生一个错误信息汇编程序会查出有一个未定义的标识符(标号或变量)存在。对于多模块程序来说,必须给汇编程序一个信息以说明其间的有些标识符是外部的,而不至于汇编程序把它们理解为
9、一些无效的标识符。此外为了允许其他模块访问本给定模块中的标识符,该给定模块必须包含一个标识符清单,以说明其中的标识符可以让其他模块访问。因此,每个模块可含有(不一定绝对含有)两个清单,一个清单表明它所访问其他模块的外部标识符(extrn),而另一个则列出它所定义的且让其他模块访问的标识符(public); 第第1414章章 模块化程序设计模块化程序设计 这两个清单靠extrn和public这两条伪指令来列出。 extrn和public伪指令的格式如下: extrn 标识符:类型, public 标识符, extrn伪指令里的标识符是被申明的外部的变量或标号,而public伪指令里的标识符是供其
10、他模块使用的变量或标号。由于在产生相应的机器代码之前,汇编语言必须要知道所有标识符的类型,以便确定指令的字节数(长度),故在extrn伪指令里的每一个标识符都伴有类型符出现。 第第1414章章 模块化程序设计模块化程序设计 对于变量来说,类型有byte、word、dword等,对于标号来说类型则有near或far。注意:标识符可以是变量、符号常量、标号和过程名。 例如:inc var1 语句,如果var1是外部变量,并且是一字变量,那么在含有这个语句的模块中必须使用下列伪指令: extrn ,var1:word 而在定义var1的模块中则一定要有下面的伪指令: public ,var1第第14
11、14章章 模块化程序设计模块化程序设计 链接程序的主要任务之一,就是检测并证实extrn语句里的每一个标识符是否与public语句的标识符相匹配,如果不相匹配,链接程序就会给出出错信息。下面给出三个模块,说明链接程序是怎样查找匹配,并指出其中错误。第第1414章章 模块化程序设计模块化程序设计 模块1:extrn var2:word,lab2:farpublic var1,lab1; data1 segment var1 db 2 var3 db ? var4 dw ?data1 ends; 第第1414章章 模块化程序设计模块化程序设计 lab1: 模块2:extrn var1:byte,v
12、ar4:wordpublic var2 链接错误,原因是模块1中public ; 没有申明匹配 data2 segment var2 dw 0 var3 db 5 dup(?)data2 ends ; 第第1414章章 模块化程序设计模块化程序设计 模块3:extrn lab1:farpublic lab2,lab3 ; 其他模块未使用lab2: 不需申明 lab3: 第第1414章章 模块化程序设计模块化程序设计 14.3 使用使用extrn和和public的范例的范例 下面的例子中含有两个模块:主模块callmul1和一个子模块submul1。主模块定义了堆栈段、数据段和指令段。数据段定义
13、了两个数据项price和qty。指令段分别把price和qty装入ax和bx寄存器,然后调用子模块。主模块内的伪指令extrn指明了本模块使用的外部模块submul1。 第第1414章章 模块化程序设计模块化程序设计 子模块内有一条伪指令public,它告诉链接程序sumul1是由其他模块调用的,同时指明此处是链接的进入点。子模块的功能是把ax寄存器的内容乘以bx寄存器的内容,所得乘积放入dx:ax这一对寄存器内。 子模块内没有定义任何数据,所以它没有数据段;也可以定义数据段,但只能在子模块中使用。 在子模块内也没有定义堆栈段,它与主模块共同使用一个堆栈。所以,在主模块中定义的堆栈,子模块也可
14、以使用。链接程序要求至少有一个堆栈段,在主模块内定义的堆栈段就可以满足要求。第第1414章章 模块化程序设计模块化程序设计 例14.1 extrn和public应用。 主模块程序清单如下:; 主模块:; filename:callmul1.asmextrn submul1:far; stack segment para stack stack dw 64 dup (?)stack ends第第1414章章 模块化程序设计模块化程序设计 ; datasgsegment para dataqty dw 0140hprice dw 2500hdatasgends; codesg segment pa
15、ra codebegin proc far assume cs:codesg,ds:datasg,ss:stack第第1414章章 模块化程序设计模块化程序设计 push ds sub ax,ax push ax movax,datasg mov ds,ax mov ax,price mov bx,qty call submul1 retbegin endpcodesg ends end begin第第1414章章 模块化程序设计模块化程序设计 子模块程序清单如下:; filename:submul1.asm;子模块:codesg segment para codesubmul1 proc f
16、ar assume cs:codesg public submul1 mul bx ret第第1414章章 模块化程序设计模块化程序设计 submul1 endpcodesg ends end submul1主模块和子模块分别汇编正确无误后,参考上节内容链接,产生一个exe文件。c:masmlink callmul1+submul1run file callmul1.exe:enter(回车)list file nul.map: enterlibraries .lib: enter第第1414章章 模块化程序设计模块化程序设计 14.4 在指令段使用在指令段使用public 在主模块的指令段和
17、子模块的指令段使用public伪指令,链接程序会把两个逻辑指令区段结合成一个实际的指令段。在例14.1的主模块和子模块中各有一处修改,均是在指令段的segment伪指令内使用public,用法如下:cod esg segment para public code第第1414章章 模块化程序设计模块化程序设计 例14.2 在指令段使用public。主模块程序清单如下:; 主模块:; filename:callmul.asmextrn submul:far; stack segment para stack stack dw 64 dup (?)stack ends第第1414章章 模块化程序设计
18、模块化程序设计 ; datasgsegment para dataqty dw 0140hprice dw 2500hdatasg ends第第1414章章 模块化程序设计模块化程序设计 ; codesg segment para public codebegin proc far assume cs:codesg,ds:datasg,ss:stack push ds sub ax,ax push ax mov ax,datasg mov ds,ax第第1414章章 模块化程序设计模块化程序设计 mov ax,price mov bx,qty call submul retbegin endp
19、codesg ends end begin第第1414章章 模块化程序设计模块化程序设计 子模块程序清单如下:; filename:submul.asm; 子模块:codesg segment para public codesubmul proc far assume cs:codesg public submul mul bx第第1414章章 模块化程序设计模块化程序设计 retsubmul endpcodesg ends end submul第第1414章章 模块化程序设计模块化程序设计 当两个段使用同一个名称(codesg)、同样的类型(code)以及同样段的组合类型(public)时
20、,链接程序会把这样的两个逻辑段组合成一个实际的物理指令区。通过汇编时产生的lst文件中的符号表,可以了解到一个指令段的情况;也可利用debug程序观察到一个指令段的情况。第第1414章章 模块化程序设计模块化程序设计 14.5 在数据段使用在数据段使用public 你可能会有这样的需求,在一个模块内要处理另外一个模块的数据。例如前面的例题中,主模块仍然定义数据price和qty;但是由子模块使用它们,把它们的值放入ax和bx。程序修改如下: 第第1414章章 模块化程序设计模块化程序设计 例14.3 在数据段使用public。主模块程序清单如下:; 主模块:; filename:callmul
21、.asmextrn submul:farpublic qty,price; stack segment para stack stack第第1414章章 模块化程序设计模块化程序设计 dw 64 dup (?)stack ends; datasgsegment para public dataqty dw 0140hprice dw 2500hdatasgends; 第第1414章章 模块化程序设计模块化程序设计 codesg segment para public codebegin proc far assume cs:codesg,ds:datasg,ss:stack push ds s
22、ub ax,ax push ax mov ax,datasg mov ds,ax call submul ret第第1414章章 模块化程序设计模块化程序设计 begin endpcodesg ends end begin 子模块程序清单如下:; filename:submul.asm; 子模块: extrn qty:word,price:word; codesg segment para public code第第1414章章 模块化程序设计模块化程序设计 submul proc far assume cs:codesg public submul mov ax,price第第1414章章
23、模块化程序设计模块化程序设计 mov bx,qty mul bx retsubmul endpcodesg ends end submul第第1414章章 模块化程序设计模块化程序设计 public qty,price ;声明主模块的qty和price为外部引用extrn qty:word,price:word;声明qty 和price是外部标识符 子模块中使用了主模块的变量,所以两个模块中都应进行声明:第第1414章章 模块化程序设计模块化程序设计 14.6 参参 数数 传传 送送 主模块调用子模块,通常也称为主程序调用子程序,主程序经常要传送一些参数给子程序,子程序运行完成后一般都要返回一
24、些信息给主程序。这种主程序和子程序间的信息传送称为参数传送或过程间的数据通信。参数传送的方法有三种:第第1414章章 模块化程序设计模块化程序设计 (1) 利用寄存器传递参数:适用参数较少时;(2) 利用存储器传递参数:适用参数较多时;(3) 利用堆栈传递参数:适用嵌套、递归情况。数据传送根据范围可分为以下几种:(1) 同一个模块内的段内参数传送。(2) 同一个模块内的段间参数传送。(3) 不同模块间的参数传送。(4) 不同语言间的参数传送第第1414章章 模块化程序设计模块化程序设计 例14.4 利用堆栈传送参数。 主模块程序清单如下:; 主模块:; filename:callmul.asm
25、 extrn submul:far ; 0000 stack segment para stack stack 0000 0040 dw 64 dup (?) ? 第第1414章章 模块化程序设计模块化程序设计 0080stack ends ; 0000datasgsegment para data 0000 0140qty dw 0140h 0002 2500price dw 2500h 0004datasg ends ; 第第1414章章 模块化程序设计模块化程序设计 0000 codesg segment para public code 0000 begin proc far assu
26、me cs:codesg,ds:datasg,ss:stack 0000 1epush ds 0001 2b c0 sub ax,ax 0003 50 push ax 0004 b8 - rmov ax,datasg 第第1414章章 模块化程序设计模块化程序设计 0007 8e d8 mov ds,ax 0009 ff 36 0002 r push price 000d ff 36 0000 r push qty 0011 9a 0000 e call submul 0016 cbret 0017begin endp 0017codesg ends end begin 第第1414章章 模块
27、化程序设计模块化程序设计 子模块程序清单如下:; filename:submul.asm ;子模块: 0000 codesg segment para public code 0000 submul proc far assume cs:codesg public submul 0000 55push bp 第第1414章章 模块化程序设计模块化程序设计 0001 8b ecmov bp,sp 0003 8b 46 08mov ax,bp+8 0006 8b 5e 06mov bx,bp+6 0009 f7 e3mul bx 000b 5dpop bp 000c ca 0004ret 4 00
28、0fsubmul endp 000fcodesg ends end 第第1414章章 模块化程序设计模块化程序设计 主模块程序在调用子模块程序submul之前,把 price和 qty都压入堆栈。 堆栈的变化如下: 16 00 xx xx 40 01 00 25 00 00 xx xx 6 5 4 3 2 1第第1414章章 模块化程序设计模块化程序设计 (1) push ds 将ds中的段地址压入堆栈。(2) push ax 把偏移地址0压入堆栈。(3) push price 把2500压入堆栈。(4) push qty 把0140压入堆栈。(5) call 把cs寄存器的内容压入堆栈。(6
29、) ip 指令指针寄存器的内容0016 也被压入堆栈。 第第1414章章 模块化程序设计模块化程序设计 被调用的子模块程序submul要用bp来取得堆栈内的参数。它的第一个操作是把bp的内容压入到堆栈保存起来。本例中bp的内容正好是0,然后把sp的内容送入bp。因为bp可以作为寻址寄存器,而sp则不行。此操作使bp的值为0072,因为sp的初值应是堆栈的大小十六进制80,每次压入堆栈一个字sp减2。堆栈指针的变化应是: 00 00 16 00 xx xx 40 01 00 25 00 00 xx xx . sp: 72 74 76 78 7a 7c 7e 80第第1414章章 模块化程序设计模
30、块化程序设计 因为现在bp的内容是0072,所以price在bp+8位置,而qty在bp+6位置。下面两条指令把这些值分别搬入ax和bx,然后作乘法。要从子模块程序回到调用程序时,先恢复bp的值0000并将sp加2,从72变成74。 最后一条指令ret,是一条子程序返回指令,它执行下列操作:第第1414章章 模块化程序设计模块化程序设计 (1) 弹出当前堆栈顶端的字1600送入ip。 (2) 把sp+2,sp从74增为76。 (3) 取出目前堆栈顶端的字(xxxx),存入cs。 (4) 把sp+2,sp从76增为78。 子程序返回指令带有参数即ret 4,指令中的4的作用是保证正确返回,将sp的值加4修正为7c。这是因为堆栈内的参数已不再需要,故予以舍弃。使用堆栈传送参数时应特别小心,sp的值弄错的话会产生预想不到的结果。第第1414章章 模块化程序设计模块化程序设计 14.7 c语言与汇编语言的链接语言与汇编语言的链接 c语言与汇编语言的链接是指c语言与汇编语言的互相调用。通常只是指从c语言调用汇编语言程序。这是因为c语言不但编程容易,而且效率高。但是,汇编语言效率最高,特别是适合对硬件的直接控制。因此,采用c语言与汇编语言混合编程的方法,能得到高质量的程序
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 网络客服工作总结及时解答解决用户问题
- 食品行业食品安全培训总结
- AIDS抗病毒治疗课件
- 2025年全球及中国血流动力学监测解决方案行业头部企业市场占有率及排名调研报告
- 2025-2030全球新能源交流继电器行业调研及趋势分析报告
- 2025-2030全球刚性墙庇护所行业调研及趋势分析报告
- 2025年全球及中国游戏视频背景音乐行业头部企业市场占有率及排名调研报告
- 2025-2030全球滑移转向岩石拾取器行业调研及趋势分析报告
- 2025-2030全球甲氧氯普胺片行业调研及趋势分析报告
- 2025年全球及中国工业级硅酸钾行业头部企业市场占有率及排名调研报告
- 充电桩知识培训课件
- 2025年七年级下册道德与法治主要知识点
- 2025年交通运输部长江口航道管理局招聘4人历年高频重点提升(共500题)附带答案详解
- 老年髋部骨折患者围术期下肢深静脉血栓基础预防专家共识(2024版)解读
- 偏瘫足内翻的治疗
- 药企质量主管竞聘
- 信息对抗与认知战研究-洞察分析
- 心脑血管疾病预防课件
- 手术室专科护士工作总结汇报
- 2025届高三听力技巧指导-预读、预测
- 苏州市2025届高三期初阳光调研(零模)政治试卷(含答案)
评论
0/150
提交评论