为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

第四章 模块化程序设计

2010-05-06 50页 ppt 977KB 54阅读

用户头像

is_597782

暂无简介

举报
第四章 模块化程序设计null第四章 模块化程序设计(6学时)第四章 模块化程序设计(6学时) 第二节 系统功能调用(2学时)退 出 第一节 模块的设计(2学时)  知 识 概 述 第三节 在C++中使用汇编语言(2学时) 第一节 模块的设计第一节 模块的设计 4.1.1 模块化程序设计的原则退 出 汇编语言只提供了模块化编程的条件,具体的模块划分、模块设计及模块间的关系要有用户自己处理。下面仅提供一些应考虑的因素。 ...
第四章  模块化程序设计
null第四章 模块化程序(6学时)第四章 模块化程序设计(6学时) 第二节 系统功能调用(2学时)退 出 第一节 模块的设计(2学时)  知 识 概 述 第三节 在C++中使用汇编语言(2学时) 第一节 模块的设计第一节 模块的设计 4.1.1 模块化程序设计的原则退 出 汇编语言只提供了模块化编程的条件,具体的模块划分、模块设计及模块间的关系要有用户自己处理。下面仅提供一些应考虑的因素。 模块的划分一般不要太大,也不宜过小,主要根据其功能而定。每个模块的功能要明确、单一。 模块的独立性要强。即模块的功能由该模块自身完成,不依赖其它模块。 4.1.14.1.1 每个模块最好只有1个入口,1个出口。 模块间的关系要明确。即上层模块可调用下层模块,下层模块可返回上层模块;反之不可以。 程序中已变化的部分与不易变化的部分分开,形成不同的模块。退 出4.1.2 进程模块的设计和调用 4.1.2 进程模块的设计和调用 一、多模块之间段的连接 多模块之间的连接,需用到SEGMENT语句提供的 连接信息。段定义的完整形式为: 段名 SEGMENT [定位类型][组合类型][类别]  段名 ENDS 1. 定位类型 对齐类型表示当前段对起始地址的要求,连接程序(LINK.EXE)按表4.1的地址格式来定位段的起始地址。退 出4.1.24.1.2 组合类型是告诉连接程序如何把本段与其它段连接的有关信息。具体的组合类型如表4.2所示. 3. 类别 类别可以使任何一个合法的标识符,但必须用但引号括起来。连接时,将把不同模块中同类别的各段在物理上相邻地连接在一起。退 出4.1.24.1.2二、模块间的交叉访问 模块间的交叉访问:是指一个模块要引用另一个模块的变量、标号等标识符。 标识符就可能有两类: 一类是供本模块使用的,我们称之为局部标识符; 另一类是同时可供本模块和其它模块使用的,我们称之为全局标识符。 1. PUBLIC伪指令 伪指令PUBLIC是用来说明,当前模块中哪些标识符是能被其它模块引用的全局标识符。其说明的一般形式如下: PUBLIC 标识符1, 标识符2, … 其中:“标识符”可以是变量名、过程名和程序标号,各标识符之间要用逗号分开。退 出4.1.24.1.2 2. 伪指令EXTRN 伪指令EXTRN是用来说明在当前模块所使用的标识符中,哪些标识符是已在其它模块中被定义为指定类型的标识符。 伪指令EXTRN的一般说明形式如下: EXTRN 标识符1:类型1,标识符2:类型2,… 其中:“标识符”和“类型”之间要用冒号“:”连接。 近模块设计及调用:数据段连接起来后在同一逻辑段内,代码也在同一逻辑代码段内,从而保证了变量、标识符无论哪个模块访问是都具有相同的段基址,这就是一种近程模块调用。例4-1就是近程模块设计及调用的一个实例。退 出4.1.24.1.2 例4-1 将第三章例3-22的浮点数结果显示。 :因为浮点数的显示按期模块化程序设计要求,我们可把其编写成子程序模块,需要显示浮点数结果时,随时调用可以完成其显示功能。若要将例3-22的浮点数结果显示,也许对例3-22程序稍作修改,已完成调用显示模块的功能。 主程序: .MODEL SMALL .386 .387 .STACK 200H .DATA EXTRN dada:DWORD l1 REAL4 0.000001退 出4.1.24.1.2 c1 REAL4 0.000001 two REAL4 2.0 .CODE .STARTUP EXTRN disp:NEAR FLD l1 FMUL c1 FSQRT FMUL two FLDPI FMUL FLD1退 出4.1.24.1.2 FDIVR FSTP dada CALL disp .EXIT 0 END ;disp子模块功能:把内存单元dada(单精度)中的浮点数显示 ;入口参数:变量dada ;出口参数:无 退 出4.1.24.1.2;算法描述: ;1)我们可先判断data的值的正负,若为负,则显示“-”。取其整数部分给变量whole, ;取其小数部分给变量fract。 ;2)取其整数部分,采用除10取余数的方法,求出整数数码(先低位后高位),加30H ;压入堆栈,然后通过出栈显示,以达到先显示高位的目的。 ;3)取其小数部分,把阶码变为原码,采用乘10取整法,求出小数部分(先高后低), ;加30H变为ASCII码显示。退 出4.1.24.1.2disp子模块源程序: .MODEL SMALL .386 .387 .STACK 128 .DATA PUBLIC dada dada DD ? status DW ? whole DD ? fract DD ? .CODE 退 出4.1.24.1.2 disps PROC MOV AH,02 MOV DL,AL INT 21H RET disps ENDP PUBLIC disp disp: FNINIT MOV AX,@data MOV DS,AX FSTCW status退 出4.1.24.1.2 OR status,0C00H FLDCW status FLD dada FTST FSTSW AX AND AX,4500h CMP AX,0100h JNZ positive MOV al,'-' CALL disps FABS退 出4.1.24.1.2positive: FLD ST FRNDINT FIST whole FSUBR FABS FSTP fract MOV EAX,whole MOV EBX,10 MOV CX,0 PUSH BX退 出4.1.24.1.2 again1:MOV EDX,0 DIV EBX ADD DL,30H PUSH DX INC CX CMP EAX,0 JNZ again1 disp1: POP AX CALL disps LOOP disp1 MOV AL,'.'退 出4.1.24.1.2 CALL disps MOV EAX,fract FSTCW status XOR status,0C00h FLDCW status FLD fract FXTRACT FSTP fract FABS FISTP whole MOV ECX,whole MOV EAX,fract退 出4.1.24.1.2SHL EAX,9 RCR EAX,CL again2:MUL EBX PUSH EAX XCHG EAX,EDX ADD AL,30H CALL disps POP EAX CMP EAX,0 JNZ again2 RET END退 出4.1.24.1.2 这就是一个近程模块的设计及调用的实例,要明白这 个问,那么就要知道简化的段定义,在.model small模式 下段的缺省属性,其如表4.3所示。退 出4.1.3 远程模块的设计及调用4.1.3 远程模块的设计及调用 远程模块的设计及调用实际上就是主模块与子模块的代码段不在同一逻辑段,数据段也可以在同一逻辑段,也可不在同一逻辑段。用户只需把握两个原则: 一是若代码段不在同一段,子模块就要设计远程的,若数据段也不在同一逻辑段,在内存变量的交叉访问时,就要用不同的段寄存器来指向不同的数据段。 二是在标号与变量在用public、extrn声明时,该语句最好放在源程序的最前面,以免引起交叉访问的时,子模块与变量无法正确的调用与引用。下面我们通过举例说明。退 出4.1.34.1.3 例4-2 显示一字符串mess。 分析:这个程序的功能很容易实现,按理讲只用dos的9号功能调用就可实现。但是为了说明远程模块的设计与调用方法,我们有意把显示功能的实现,用显示单个字符的子模块实现,若要显示字符串,通过循环调用子模块实现。 LI4-2ZHU.ASM主模块源程序: EXTRN bChar:BYTE EXTRN out_routine:FAR stack SEGMENT para stack 'stack' DW 256 DUP(?) stack ENDS退 出4.1.34.1.3 code SEGMENT 'code' ASSUME CS:code,DS:code messe DB 'this is a routine',13,10 main: CLD MOV AX,CS MOV DS,AX MOV SI,OFFSET messe退 出4.1.34.1.3 loop1: LODSB MOV es:bChar,AL CALL out_routine CMP es:bChar,10 JNE loop1 MOV AH,4CH INT 21H code ENDS END main退 出4.1.34.1.3;out_routine 子模块功能:把内存单元bChar中的字符显示 ;入口参数:变量bChar ;出口参数:无 ;算法描述:我们通过dos的2号功能调用来实现单个字符的显示。 out_routine子模块源程序: PUBLIC bChar PUBLIC out_routine code SEGMENT 'code' ASSUME CS:code,ES:code bChar DB ?退 出4.1.34.1.3 out_routine PROC FAR MOV AX,CS MOV ES,AX MOV DL,ES:bChar MOV AH,2 INT 21H RETF out_routine ENDP code ENDS END退 出4.1.4 子程序库4.1.4 子程序库 库文件对学过C/C++语言程序设计的读者来说应该是不会陌生的,该语言的程序设计环境提供了大量的库文件,也就是说,提供了大量的标准函数,用户在调用某一库中的函数时,只需用“#include”声明。在本节里,介绍读者如何创建自己的库文件。退 出4.1.44.1.4一、建立库文件 假设现有目标文件sub1.obj、sub2.obj和sub3.obj,要用它们建立库文件mylib.lib。可用下列方法来建立该库文件: 方法1:所有目标文件都准备好了,可一次性把它们加入到库文件中。 …>lib  mylib +sub1 +sub2 +sub3 方法2:随着目标文件的逐个生成,而依次把它们加入到库文件中。 …>lib  mylib +sub1 …>lib  mylib +sub2 …>lib  mylib +sub3退 出4.1.44.1.4二、库文件应用 例如,我们用建立库文件的方法,完成例4-2。例4-2主程序及子程序的建立及宏汇编过程同上,现已生成了目标文件LI4-2ZHU.obj及LI42ZI.obj(因为库命令输入的目标文件名不允许用“-”,所以取消了该字符),用LI4-2ZI.obj建立库文件mylib.lib。用下列命令: …>lib mylib LI42ZI 连接目标文件LI4-2ZHU及库文件mylib.lib: …>link LI4-2ZHU 执行LI4-2程序: …>LI4-2退 出4.1.44.1.4三、库文件与子程序不同 方法1:直接连接目标文件而生成可执行文件。 这种方法简单、方便,也是常用的一种方法,但在连接时,LINK程序会把目标文件中的所有代码都嵌入到执行文件中,从而使得:包含在某目标文件中、但并没有被调用的子程序代码也出现在执行文件中。这种情况无疑增加了执行文件的字节数。 方法2:采用子程序库的方法。 库文件可以把它看成是子程序的集合。库文件中存储着子程序名、子程序的目标代码以及连接所需要的重定位信息。当某目标文件与库文件相连接时,LINK程序只把目标文件所用到的子程序从库文件中找出来,并合并到最终的可执行文件中,而不是把库中所含的全部子程序都纳入最后的可执行文件。退 出第二节 系统功能调用第二节 系统功能调用 BIOS层模块、DOS层功能模块:BIOS层模块、DOS层功能模块对用户来说均可看成中断处理程序,它们的入口都在中断向量表中。用户使用汇编语言可以直接调用它们,这极大的方便了用户对微机系统的开发。 Windows层功能调用:Windows 系统功能调用是通过Win32 API函数调用来实现的。退 出系统功能调用4.2.1 BIOS层功能模块的调用 4.2.1 BIOS层功能模块的调用 基本输入输出系统是操作系统核心。它的主要功能是驱动系统的外部设备,如磁盘驱动器、显示器、键盘、打印机及异步通信接口等。用户不必过多地关心有关设备的物理性能及接口方面的细节,即不用直接使用IN或OUT语句,只需调用相应的子程序即可实现设备的使用。其调用子程序时需完成下列3步: 第一,置入口参数;第二,选功能号于AH中; 第三,使用“INT 中断号”语句调用。 基本输入输出系统中子程序的中断号为5—1FH。使用“INT 中断号”语句即可调用相应的子程序,然后就可以得到结果和输出参数。下面我们介绍最常用的BIOS调用。退 出4.2.14.2.1一、BIOS中的键盘输入 在BIOS系统中,提供了中断16H来实现键盘输入功能,其具体的功能如下: 00H——从键盘读一个字符,输入字符不回显。 01H——判断键盘缓冲区内是否有字符可读。 02H——读取当前键盘状态字。 有关中断功能的详细描述和调用参数在此从略,需要查阅者可参阅附录3。例如从键盘读入一个字符,需完成以下3步: 第一,入口参数:无; 第二,AH00H; 第三,INT 16H; 其出口参数,也就是键入的字符的ASCII码在AL中。退 出4.2.14.2.1 二、BIOS中的屏幕输出 BIOS系统提供了中断10H来实现各种屏幕处理功能。其具 体的功能如下: 00H—设置显示器模式 01H—设置光标形状 02H—设置光标位置 03H—读取光标信息 05H—设置显示页 06H、(07H)—向上滚屏和(向下滚屏) 08H—读光标处的字符及其属性 09H—在当前光标处按指定属性显示字符 0AH—在当前光标处显示字符 0CH—写图形象素 0DH—读图形象素 0FH—读取显示器模式 退 出4.2.14.2.1 例如在显示器上显示一个字符需完成以下3步: 第一,入口参数:AL需显示字符的ASCII码,BH 页号,BL 字符的显示属性。 第二,AH09H; 第三,INT 10H 执行完成后,就会在显示器上按指定的字符属性显示该字符。退 出4.2.2 DOS层功能调用 4.2.2 DOS层功能调用 DOS层的功能模块在系统盘中,系统启动时被装入内存。它们的功能比BIOS更加广泛完整,主要功能是文件管理、存储管理,设备管理等。 在DOS下,其调用子程序时需完成下列3步: 第一,置入口信息; 第二,选功能号于AH中; 第三,通常使用“INT 21H”语句调用。退 出4.2.24.2.2一、DOS中的键盘输入 键盘输入是一种最常用的输入方式,所以,在DOS操作系统中,提供了能实现各种键盘输入的功能,INT 21H中的相关功能如下: 01H——带回显的键盘输入 06H——控制台的输入/输出:当 DL=0FFH,表示键盘输入 08H——不回显的键盘输入 0AH——键盘输入字符串 0BH——检查键盘有无输入 0CH——清除输入缓冲区的输入 功能退 出4.2.24.2.2例如带回显的键入单个字符的功能调用,需完成以下3步: 第一,选功能号于AH中; 第二,入口参数:无; 第三,通常使用“INT 21H”语句调用。 执行完成后,用户可从AL取出输入字符的ASCII码。 又如键入字符串功能调用,需完成以下3步: 第一,功能号:AH0AH; 第二,入口参数:DS:DX存储键入字符串的首地址, (DS:DX)=允许键入字符的个数; 第三,中断指令:INT 21H。 执行完成后,用户可从DS:(DX+2)单元取出输入字符的 ASCII码,从DS:(DX+1)取出实际键入字符的个数。退 出4.2.24.2.2二、DOS中的显示器输出 屏幕输出是最常用的一种输出形式,DOS操作系统 提供了几种实现屏幕输出的功能调用。INT 21H中的相关 功能如下: 02H—显示的字符 06H—控制台的输入/输出:当DL≠0FFH,表示显示字符 09H—在屏幕上显示一个字符串 例如显示单个字符,需完成以下3步: 第一,功能号:AH02H; 第二,入口参数:DL要显示字符的ASCII码; 第三,INT 21H 执行完成后,屏幕上就会显示出该字符。退 出4.2.24.2.2又如显示一个字符串,需完成以下3步: 第一,功能号:AH09H; 第二,入口参数:DS:DX字符串首地址,字符串是以 “$”结束; 第三,INT 21H 执行完成后,屏幕上就会显示出该字符串。 例4-3 用键盘最多输入10个字符,并存入内存变量Buff中,若按“Enter”键,则表示输入结束。 分析:实现该功能,我们可直接调用系统功能模块,可用DOS层,也可用BIOS层,但可以看出,使用DOS层的程序简单,容易。下面我们给出了分别用BIOS层和DOS层的功能调用实现的程序。退 出4.2.24.2.21. 用BIOS层功能调用实现的源程序: .MODEL SMALL cr EQU 0DH .STACK 200H .DATA Buff DB 10 DUP(?) .CODE .STARTUP MOV CX, 0AH LEA BX, Buff .REPEAT MOV AH, 0H INT 16H 退 出4.2.24.2.2 .BREAK .IF AL==cr MOV [BX], AL INC BX .UNTILCXZ .EXIT 0 END 2. 用DOS层功能调用实现的源程序: .MODEL SMALL .STACK 200H .DATA 退 出4.2.24.2.2 Buff DB 10, ?, 10 DUP(?) .CODE .STARTUP LEA DX, Buff MOV AH, 0AH INT 21H .EXIT 0 END 可以看出,用DOS层的功能调用程序要简单的多。退 出4.2.3 WINDOWS层功能模块调用 4.2.3 WINDOWS层功能模块调用 Win32程序是构筑在Win32 API基础上的。 通过Win32 API调用Windows 系统相当于在MS-DOS 中通过中断方式调用系统功能。Win32 的系统功能模块放在Windows 的动态链接库中,DLL 是一种Windows 的可执行文件。 Win32 API 的核心由3 个DLL 提供,它们是: 退 出4.2.34.2.3 KERNEL32.DLL—系统服务功能。包括内存管理、任务管理和动态链接等。 GDI32.DLL—图形设备接口。利用VGA 与DRV 之类的显示设备驱动程序完成显示文本和矩形等功能。 USER32.DLL—用户接口服务。建立窗口和传送消息等。 当然,Win32 API 还包括其它很多函数,这些也是由DLL 提供的,不同的DLL 提供了不同的系统功能。退 出4.2.34.2.3一、API函数调用 C语言的消息框函数的声明: int MessageBox( HWND hWnd, // handle to owner window LPCTSTR lpText, // text in message box LPCTSTR lpCaption, // message box title UINT uType // message box style ); 最后还有一句说明: Library: Use User32.lib.退 出4.2.34.2.3 汇编的声明格式: MessageBox Proto hWnd:dword,lpText:dword,lpCaption:dword,uType:dword 上面最后一句Library: Use User32.lib 则说明了这个函数包括在User32.dll 中。 汇编中调用MessageBox 函数的方法是: push uType push lpCaption push lpText push hWnd call MessageBox退 出4.2.34.2.31. 使用invoke 语句 Microsoft 在MASM6.11中提供了一条伪指令实现利用堆栈传递参数的子程序调用,那就是invoke 伪指令,它的格式是: invoke 函数名[,参数1][,参数2].. 对MessageBox 的调用在MASM 中可以写成: invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK退 出4.2.34.2.32. API 函数的返回值 有的API 函数有返回值,如MessageBox 定义的返回值是int类型的数,返回值的类型对汇编程序来说也只有dword 一种类型,它永远放在eax 中。如果要返回的内容不是一个eax所能容纳的,Win32 API 采用的方法一般是返回一个指针,或者在调用参数中提供一个缓冲区地址,干脆把数据直接返回到缓冲区中去。 3. 函数的声明 在调用API 函数的时候,函数原型也必须预先声明,否则,编译器会不认这个函数。invoke伪指令也无法检查参数个数。声明函数的格式是: 函数名proto [距离] [语言] [参数1]:数据类型,[参数2]:数据类型, 退 出4.2.34.2.34.include 语句 现在回到Win32 Hello World 程序,这个程序用到了两个API 函数:MessageBox 和ExitProcess,其函数声明分别在User32.dll 和Kernel32.dll 中,在MASM32 工具包中已经包括了所有DLL 的API 函数声明列表,每个DLL对应文件,在源程序中只要使用include 语句包含进来就可以了: include user32.inc include kernel32.inc include 语句的语法是: include 文件名 或include <文件名> 当遇到要包括的文件名和MASM的关键字同名等可能会引起编译器混淆的情况时,可以用<>将文件名括起来。退 出4.2.34.2.35. includelib语句 为了告诉链接程序使用哪个导入库,使用的语句是: includelib 库文件名 或includelib <库文件名> 和include 的用法一样,在要包括让编译器混淆的文件名时,可以用<>将文件名括起来。例3-23程序用到的两个API 函数MessageBox 和ExitProcess 分别在User32.dll 和Kernel32.dll 中,那么在源程序使用的相应语句为: includelib user32.lib includelib kernel32.lib 和include 语句的处理不同,includelib 不会把.lib 文件插入到源程序中,它只是告诉链接器在链接的时候到指定的库文件中去找而已。退 出4.2.34.2.3二、参数中的等值定义 再回过头来看显示消息框的语句: invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK uType — 定义对话框的类型,这个参数可以是以下参数: 要定义消息框上显示按钮,用下面的某一个标志: MB_ABORTRETRYIGNORE — 消息框有三个按钮:“终止”,“重试”和“忽略”。 MB_HELP — 消息框上显示一个“帮助”按钮,按下后发送WM_HELP 消息。 MB_OK — 消息框上显示一个“确定”按钮,这是默认值。 退 出4.2.34.2.3 MB_OKCANCEL — 消息框上显示两个按钮:“确定”和“取消”。 MB_RETRYCANCEL — 消息框上显示两个按钮:“重试”和“忽略”。 MB_YESNO —消息框上显示两个按钮:“是”和“否” MB_YESNOCANCEL — 消息框上显示三个按钮:“是”、“否”和“取消”。 要在消息框中显示图标,用下面的某一个标志: MB_ICONWARNING — 显示惊叹号图标。 MB_ICONINFORMATION — 显示消息图标。 MB_ICONASTERISK — 显示危险图标。 MB_ICONQUESTION — 显示问号图标。 MB_ICONSTOP — 显示停止图标。退 出第三节 在C++中使用汇编语言 第三节 在C++中使用汇编语言 16位的应用程序用C/C++实现时,通常使用Microsoft Visual C++ for DOS平台,而32位的应用程序用C++实现时,通常使用Microsoft Visual C++ for Windows平台。在用户使用汇编语言与C++实现混合编程时16位应用程序于32位应用程序的主要区别,就是Microsoft Visual C++ for Windows应用程序试图用DOS INT 21H功能,程序可能会崩溃,因为其不允许直接调用DOS。下面,我们主要介绍32位应用程序中汇编语言与C++的混合编程思想,从而对于16位的混合编程方法也就随之了解。退 出 4.3.1 在16位应用程序中使用汇编语言与C++语言4.3.2 在32位应用程序中使用汇编语言与C++语言 4.3.2 在32位应用程序中使用汇编语言与C++语言 汇编与C++混合编程的一种较为简单的方法是在C++程序中内嵌汇编语句,嵌入汇编语言的语法如下: _asm <汇编指令> <; 汇编指令>  注意:这里的分号 ';' 不是汇编语言中起注释作用的分号,而是作为语句的分隔符。 若C语言源程序中嵌入一条汇编语句,则可按下列方式来做: _asm mov ax, data 若要嵌入一组汇编语句,则需要用括号 '{' 和 '}' 把它们括起来。 退 出4.3.24.3.2 asm {    mov ax, data1   xchg ax, data2   mov data1, ax     //实现整型变量data1和 data2之值的交换 } 例4-4 以二进制到十六进制之间的任意进制显示键入的数 值(032767)。 分析:首先,把输入的ASCII数码二进制数; 其次, 通过循环调用disps函数将该数转换为二进 制到十六进制之间的任意进制 的ASCII数 码,再显示。退 出4.3.24.3.2源程序: #include char *buffer="Enter a nember between 0 and 32767:"; char *buffer1="Base"; int a,b=0; //disps子函数功能:将二进制数data转换为base进制数显示; //入口参数:int型的基数base,int 型的data; //出口参数:无; //算法描述:除基数取余数法,直至商为0。 void disps(int base,int data){ int temp; _asm{ mov eax,data mov ebx,base push ebx退 出4.3.24.3.2 Top1: mov edx,0 div ebx push edx cmp eax,0 jnz top1 top2: pop edx cmp edx,ebx je top4 add edx,30h cmp edx,39h jbe top3 add edx,7退 出4.3.24.3.2top3: mov temp,edx } _putch(temp); _asm {jmp top2} top4:; } void main(){ int i; _cputs(buffer); a=_getche(); while(a>='0'&&a<='9'){ _asm{sub a,30h} b=b*10+a; a=_getche(); }退 出4.3.24.3.2 _putch(10); _putch(13); for(i=2;i<17;i++){ _cputs(buffer1); disps(10,i); _putch(' '); disps(i,b); _putch(10); _putch(13); } } 退 出4.3.3 在C/C++应用程序中调用汇编语言程序 4.3.3 在C/C++应用程序中调用汇编语言程序 下面我们通过例4-5来说明C++如何调用独立的汇编子模块。 例4-5 将一字符串反序输出显示。 分析:我们利用C++来实现字符串的显示功能,用汇编模块实现反序功能。 ;Reverse子模块功能:将arraychar指向的字符串反序 ;入口参数:char型的指针arraychar ;出口参数:无 ;算法:逐一取出字符入栈,利用堆栈的“后进先出”存储原则,然后逐一出栈,再从 ;字符的首地址逐一存入。退 出4.3.34.3.3 .386 .model flat,c .stack 1024 .code public Reverse Reverse proc uses esi,arraychar:ptr mov esi,arraychar push 0 .repeat mov al,[esi] push ax inc esi退 出4.3.34.3.3 .until byte ptr[esi]==0 mov esi,arraychar .while 1 pop ax .break .if al==0 mov [esi],al inc esi .endw ret Reverse endp end退 出4.3.34.3.3主模块源程序: #include extern "C"void Reverse(char*); char chararray[30]="This is the mix programme!"; void main(){ cout<
/
本文档为【第四章 模块化程序设计】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索