汇编语言程序设计及上机指导+第7章+高级汇编语言程序设计.ppt_第1页
汇编语言程序设计及上机指导+第7章+高级汇编语言程序设计.ppt_第2页
汇编语言程序设计及上机指导+第7章+高级汇编语言程序设计.ppt_第3页
汇编语言程序设计及上机指导+第7章+高级汇编语言程序设计.ppt_第4页
汇编语言程序设计及上机指导+第7章+高级汇编语言程序设计.ppt_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

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

文档简介

第7章高级汇编语言程序设计,【本章提要】本章叙述几种难道较大的程序设计技术,包括CPU工作模式的切换,以及32位和64位Windows汇编语言程序的设计,最后讲述汇编语言和高级语言的简单混合编程。【学习目标】掌握32位、64位Windows程序的汇编语言设计的基本方法简单掌握MASM32以及FASM汇编工具的基本应用简要掌握汇编语言和高级语言的混合编程及其汇编、编译和链接过程,2020/6/9,7.1保护模式编程介绍,7.1.1保护模式的特征实模式下的寄存器、寻址方式和指令等基本概念,除特别说明外在保护方式下仍然保持。尽管实方式下CPU的功能要大大超过其先前的处理器,但只有在保护方式下,才能发挥其更大的作用。在保护方式下,全部32条地址线有效,可寻址高达4G字节的物理地址空间;扩充的存储器分段管理机制和可选的存储器分页管理机制,不仅为存储器共享和保护提供了硬件支持,而且为实现虚拟存储器提供了硬件支持;支持多任务,能够快速地进行任务切换和保护任务环境;4个特权级和完善的特权检查机制,既能实现资源共享又能保证代码和数据的安全和保密及任务的隔离;支持虚拟8086方式,便于在保护方式下同时又能执行8086程序。,2020/6/9,7.1.2保护模式编程,保护模式编程的要点就是如何实现实模式和保护模式的相互切换。一、从实模式切换到保护模式从实模式切换到保护模式一般需要两个步骤:作好切换到保护模式下的准备;切换到保护模式。主要准备工作就是建立全局描述符表,并使GDTR指向GDT,因为切换到保护模式下,至少要将代码段的选择子装入到CS中。,2020/6/9,1)定义好段描述符的结构:DESCRIPTORSTRUCT;每个段描述符占8个字节LIMITDW0;段界限BASELDW0;段基址的低16位BASEMDB0;段基址的1623位ATTRIBUTESDW0;段属性BASEHDB0;段基址的高8位,2431DESCRIPTORENDS2)定义好伪描述符:PDESCRIPTORSTRUCT;装入48位全局描述符表寄存器时要用到LIMITDW0;段界限BASEDD0;段基址PDESCRIPTORENDS3)通常要定义一个段间跳转的宏,这样的话就可以保证在进入保护模式时将代码段的选择子装入到CS寄存器。JUMPFARMACROselector,offsetsDB0EAH;0EAH为JUMP指令的机器码DWoffsets;段偏移DWselector;段选择子ENDM,2020/6/9,4)打开A20地址线:保护模式下访问的地址空间超过1M,所以必须要用到A20地址线。ENABLE_A20MACRO;通过92H号端口的输出,可以使地址线;A20打开,能够被访问PUSHAXINAL,92HORAL,2;在92H号端口的d1位输出1,打开A20地址线OUT92H,ALPOPAXENDM5)切换到保护模式下的最关键的动作为,将CR0寄存中的第0位置1。TO_PROTECTMACROMOVEAX,CR0ORCR0,1MOVCR0,EAXENDM,2020/6/9,二、保护模式切换到实模式显而易见,在保护模式返回到实模式时,只要做和上述的几个动作相反的动作就行了。主要要做好以下几个方面:1)定义一个宏,回到实模式,将CR0寄存中的第0位清0。TO_REALMACROmoveax,cr0andeax,0fffffffehmovcr0,eaxENDM2)定义一个宏,关闭A20地址线。DISABLE_A20MACROPUSHAXINAL,92HANDAL,0FDH;在92H号端口的d1位输出0,关闭A20地址线OUT92H,ALPOPAXENDM3)恢复DS,使其内容为数据段基址,可用以下两条指令:movax,DATAmovds,ax4)用一个段间跳转的宏,清指令预取队列,使CS内容为代码段基址。,2020/6/9,三具体实现方法下面的例子给出了如何从实模式转换到保护模式,并在保护模下访问680000H单元开始的内容(数据段基地址为680000H),最后又如何从保护模式返回到实模式的方法,程序结构片段如下:.386P;定义使用386指令集datasegmentuse16;定义16位数据段GDTLABELBYTE;定义全局描述符表EMPTYDESCRIPTOR;空描述符,CODESEGDESCRIPTOR0FFFFH,98H,;代码段的描述符CODE_SEL=CODESEG-GDT;代码段描述符的选择子DATASEGDESCRIPTOR0FFFFH,0H,68H,92H,;数据段描述符,即680000HDATA_SEL=DATASEG-GDT;数据段选择子GDTLEN=$-GDTVGDTRPDESCRIPTORGDTLEN-1,dataends,2020/6/9,codesegmentuse16assumecs:code,ds:datastart:movax,datamovds,axmovbx,16mulbx;设置全局描述表GDT基址,因为现在还处在实模式下,所以段地址要左移4位addax,offsetGDTadcdx,0movwordptrVGDTR.BASE,ax;设置全局描述符表寄存器GDTR的内容movwordptrVGDTR.BASE+2,dxmovax,cs;以下为设置代码段描述符mulbxmovCODE.BASEL,axmovCODE.BASEM,dlmovCODE.BASEH,dhLGDTFWORDPTRVGDTR;加载GDTRCLI;关中断ENABLE_A20;打开A20地址线TO_PROTECT;切换到保护模式JUMPFARCode_Sel,;清指令预取队列,PROTECT:;现在开始在保护方式下运行movax,Data_Selmovds,ax;加载数据段描述符;根据具体任务要求实现程序段;以下为回到实模式的步骤JUMPFAR,;清指令预取队列REALMODE:TO_REAL;回到实方式DISABLE_A20;关闭A20地址线movax,DATAmovds,axSTI;开中断;根据具体任务要求实现程序段codeendsendstart,2020/6/9,7.2用汇编语言编写Windows应用程序,7.2.1Windows与DOS区别一、工作方式16位DOS操作系统工作于实地址方式,是单任务操作系统,一个正在运行的程序独占了所有系统资源,只有一个特权级别,任何程序和操作系统都是同级的。32位Windows操作系统运行于IA-32微处理器的保护地址模式,是多任务操作系统,系统资源由多个程序共享,系统存在两个特权级别,操作系统运行在最高级别0级,应用程序都运行于最低级别3级。64位Windows操作系统运行于64位模式下,和32位Windows操作系统的特征基本类似,但只能工作在支持EM64T技术的IA-32或IA-64处理器环境中,目前主要有64位版的WindowsXP和64位版的WindowsVista。,2020/6/9,二、内存空间DOS平台下只能访问1MB物理存储空间,而且内存必须分成不大于64KB的逻辑段,由不同的段寄存器来寻址不同的段。32位Windows平台下,直接使用32位地址来寻址一个不分段的、达4GB的主存空间,Windows应用程序只有代码段和数据段,无须和段寄存器打交道。只有一种内存管理模式FLAT。64位Windows平台下,默认采用64位线性地址空间,支持40位物理地址空间,通常不采用分段方式,而是将CS,DS,ES和SS的段基址看成0,这样线性地址等于有效地址,也是只有一种FLAT存储管理模式。,2020/6/9,三、系统功能调用DOS操作系统为程序员提供中断服务程序,以中断调用的方法进行系统功能调用,而且DOS中断调用采用寄存器传递参数;Windows32/64操作系统提供了动态链接库DDL,利用应用程序接口API(也曾被称为软件开发包SDK)调用动态链接库中的函数,应用程序利用堆栈传递参数。四、输入输出方式DOS平台下的程序以字符方式输出信息,程序需要用户输入数据时就停下来,一直等到用户输入了数据之后才继续执行;Windows32/64程序采用图形用户界面进行信息的输入输出,用户的每个操作都会形成消息(Message)传递给相应程序,各个同时运行的程序彼此之间相对独立。,2020/6/9,masm32子文件夹介绍,2020/6/9,MASM32QEDITOR.EXE集成开发工具,2020/6/9,在windows.inc文件中关于UType的定义:MB_ABORTRETRYIGNORE;消息框有三个按钮:.终止.,.重试.和.忽略.MB_HELP;消息框上显示一个.帮助.按钮,按下后发送WM_HELP消息MB_OK;消息框上显示一个.确定.按钮,这是默认值MB_OKCANCEL;消息框上显示两个按钮:.确定.和.取消.MB_RETRYCANCEL;消息框上显示两个按钮:.重试.和.忽略.MB_YESNO;消息框上显示两个按钮:.是.和.否.MB_YESNOCANCEL;消息框上显示三个按钮:.是.、.否.和.取消.要在消息框中显示图标,用下面的某一个标志:MB_ICONWARNING;显示惊叹号图标MB_ICONINFORMATION;显示消息图标MB_ICONASTERISK;显示危险图标MB_ICONQUESTION;显示问号图标MB_ICONSTOP;显示停止图标,2020/6/9,简单Win64程序设计,formatPE64GUI;定义64位程序entrystart;指定程序入口为start标号section.codecodereadableexecutable;定义代码段start:;程序入口标号subrsp,8*4;为API调用预留堆栈空间并使rsp指针64位对齐movr9d,1;r9d寄存器用于传送MessageBoxA函数的按钮参数lear8,caption;r8寄存器用于传送MessageBoxA函数的标题参数leardx,message;rdx寄存器用于传送MessageBoxA函数的文本参数movrcx,0;rcx寄存器用于传送消息框的类型参数callMessageBoxA;调用MessageBoxA函数,显示消息框movecx,eax;把eax中消息框的返回值保存到ecxcallExitProcess;调用ExitProcess函数,结束程序并返回到OSsection.datadatareadablewriteable;定义数据段captiondbWindows64位应用程序,0;定义消息框要显示的标题messagedb好好学习,天天向上!,0;定义消息框要显示的文本,用汇编语言开发64位Windows应用程序,首先要有64位的处理器和操作系统软硬件支持,另外还要选择合适的64位汇编工具。,2020/6/9,;以下是为程序的链接和执行所进行的辅助定义section.idataimportdatareadablewriteable;定义入口数据段dd0,0,0,RVAkernel_name,RVAkernel_table;对程序装入时的预定义,以及对;所调用函数和API动态链接库的dd0,0,0,RVAuser_name,RVAuser_table;声明等dd0,0,0,0,0kernel_table:ExitProcessdqRVA_ExitProcessdq0user_table:MessageBoxAdqRVA_MessageBoxAdq0kernel_namedbKERNEL32.DLL,0user_namedbUSER32.DLL,0_ExitProcessdw0dbExitProcess,0_MessageBoxAdw0dbMessageBoxA,0,2020/6/9,7.3.1汇编指令的嵌入式编程,汇编指令的嵌入式编程就是在高级语言程序中,嵌入汇编语言指令。一、嵌入方法在TurboC语言程序中,嵌入汇编语言指令是在汇编语句前加一个asm关键字。语法如下:ASM其中,操作码是处理器指令或若干伪指令;操作数是操作码可接受的数据,它可以是指令允许的立即数、寄存器名,还可以是C语言程序中的常量、变量和标号。内嵌的汇编语句可以用分号“;”结束,也可以用换行符结束;一行中可以有多个汇编语句,相互间用分号分隔,但不能跨行书写。嵌入汇编语句的分号不是注释的开始;要对语句注释,应使用C语言的注释,如*。例如:ASMMOVAX,BX;/*AXBX*/ASMPOPAX;ASMPOPBX;ASMRET;/*3条语句可以写在一行*/ASMADDAX,BX/*ASM语句在C程序中可以不用分号结尾*/,2020/6/9,在TurboC2.0中,具体说明如下:1)持8086指令集,包括传送、运算、串操作、转移等全部指令。当内嵌80286指令时,必须使用TCC命令行选择项-L进行编译,以便使汇编程序能够识别这些指令。2)仅支持若干汇编语言伪指令,它们是变量定义伪指令dbdwdd和外部数据说明伪指令extern。3)TurboC语言中可以直接使用通用寄存器和段寄存器,只要在寄存器名字前加一个下划线即可,但寄存器名字要大写。4)嵌入式汇编语言中,可以使用无条件、条件转移指令和循环指令,但它们只能在一个函数内部转移。ASM语句也不能定义标号,转移指令的目标必须是C语言程序的标号。5)若要嵌入一组汇编语句,则需要用括号和把它们括起来。例如:ASMMOVAX,DATA1/*实现整型变量DATA1和DATA2之值的交换*/XCHGAX,DATA2MOVDATA1,AX,2020/6/9,【例】在C语言源程序中嵌入汇编语言语句实现3个整数求和。intsum3(intvar1,intvar2,intvar3)ASMPUSHAXASMMOVAX,VAR1ASMADDAX,VAR2ASMADDAX,VAR3ASMMOVVAR1,AXASMPOPAXreturn(var1)main()/*C语言主程序*/printf(“%dn”,sum3(10,20,30);,2020/6/9,二、嵌入汇编的编译过程,C语言程序中含有嵌入式汇编语言语句时,C编译器要完成以下三个步骤:代码转换:将.C扩展名源程序的代码转换成.ASM扩展名的汇编语言代码源文件;编译:用默认的汇编程序TASM.EXE把产生的.ASM汇编语言源文件编译成.OBJ目标文件,TASM与MASM基本相同,也可以在编译的命令行中加上-EMASM选项用MASM.EXE来编译。注意TuorboC2.O是早期开发的软件,只考虑了与早期MASM版本的兼容,而不能与MASM6.x很好的配合使用;用TLINK将目标文件链接成.exe可执行文件。TurboC2.0在编译含内嵌汇编语句的程序时,只能采用命令行方式,通过执行TCC.EXE来完成。同时要使用-B命令行选项编译连接,也可以在C源程序中使用了#pragmainline预处理语句,这时就可以不用命令行选项-B了。,2020/6/9,【例】将字符串中的大写字母转变为小写字母并显示出来#include“stdio.h”voidlower(char*dvar,char*svar)ASMMOVSI,SVAR*DVAR和SVAR是地址指针*ASMMOVDI,DVARASMCLDagain:ASMLODSB*C语言定义的标号*ASMCMPA1,AASMJBCOPY*转移到C的标号*ASMCMPA1,ZASMJACOPY*不是A到Z之间的字符原样复制*ASMADDA1,20H*是小写字母转换成大写字母*copy:ASMSTOSB*C语言定义的标号*ASMCMPAL,0*C语言中字符串用0结尾*ASMJNZAGAIN;main()*主程序*charoldstr”IAMagoodSTUDENT!”;charnewstr100;lower(newstr,oldstr);printf(“OLDSTRINGIS%sn”,oldstr);printf(“NEWSTRINGIS%sn”,newstr);,2020/6/9,编辑完成后,假定该文件名为,在命令行输人如下编译命令(选项-I和-L分别指定头文件和库函数的所在目录):TCCBIincludeLlibexample.c生成可执行文件example.exe,程序运行后输出的结果将是:OLDSTRINGISIAMagoodSTUDENT!NEWSTRINGISiamagoodstudent!由上例可以看出,嵌入汇编方式把插入的汇编语言语句作为C语言的组成部分,不使用完全独立的汇编模块,所以比调用汇编子程序更方便、快捷,并且在大存储模式、小存储模式下都能正常编译通过。,2020/6/9,7.3.2多模块混合编程,各种语言的程序分别编写,利用各自的开发环境编译形成.obj目标模块文件,然后将它们连接在一起,最终生成可执行文件。一、混合编程的规则1命名规则C语言编译系统在编译C语言源程序时,要将其中的变量名、过程名、函数名等标识符前面加下划线“_”;但是,如果汇编语言程序设置采用C语言类型,则不必在标识符前加下划线。而且对标识符的要求是取前8个字符有效还注意区别字母的大小写。2声明规则在C语言程序中,对所要调用的外部过程、函数、变量都要用EXTERN来说明,并且要求放在主调用程序之前,一般放在各函数体外部,说明形式如下:EXTERN返回值类型函数名称(参数类型表);EXTERN变量类型变量名;其中,返回值类型和变量类型是C语言中函数、变量中所允许的任意类型,当返回值类型空缺时,默认为int型。例如:EXTERNlongsome(int,int);/*SOME函数返回值为LONG型*/EXTERNgood(int,int);/*GOOD函数返回值缺省为INT型*/EXTERNchartempvar/*TEMPVAR变量为CHAR型*/经说明后,这些外部变量、过程、函数可在C程序中直接使用,函数的参数在传递过程中要求参数个数、类型、顺序要一一对应。和纯汇编语言多模块编程要求一样,汇编语言程序的标识符(子程序名和变量名)为了让C语言程序能够调用它,必须用public语句定义它们。,2020/6/9,3寄存器使用规则1)通用寄存器AX、BX、CX、DX和ES,在汇编语言子程序中通常是可以任意使用的。一般传递返回值的任务由AX和DX寄存器承担。标志寄存器也可以任意改变;2)段寄存器DS、CS和SS及BP、SP,如果汇编语言子程序要使用它们,必须先进行保护(入栈),退出前再加以恢复(出栈);3)变址寄存器SI和DI一般被作为TurboC寄存器变量,所以汇编语言子程序使用SI和DI时也要进行保护和恢复。但如果C程序没有用到寄存器变量,则汇编语言子程序不必多此一举。4存储模式规则TurboC提供了6种存储模式,分别对应了汇编程序的前6种相应存储模式。为了使汇编语言程序与TurboC语言程序连接到一起,两者必须具有相同的存储模式。汇编语言程序采用.model伪指令,TurboC利用TCC命令行的选项-m指定各自的存储模式。相同的存储模式将自动产生相互兼容的调用和返回类型;另外,汇编程序的段定义伪指令.Code、.data等也会产生与TurboC相兼容的段名和属性,2020/6/9,模块的编译和连接,采用AX寄存器传递返回,通过堆栈传递参数。【例】C语言程序调用汇编语言子程序,计算周工资并显示总和。假定C语言主程序保存在文件c_main.c中,内容如下:/*WEEKPAY是外部函数*/externunsignedshortweekpay(int,wages)intwages5=100,200,120,280,150main()printf(“WEEKLYPAY=%u”,weekpay(wages);/*调用WEEKPAY函数*/,2020/6/9,假定汇编语言子程序保存在文件masm_sub.asm中,内容如下:.MODELMEDIUM,C;采用中型存储模式和C语言类型.CODEPUBLICWEEKPAY;指明该过程可供外部模块使用WEEKPAYPROCFAR;采用了一致的命名约定,共用标识符不必加下划线PUSHBP;保护寄存器BP,子程序第一条语句必须是它MOVBP,SP;取当前栈顶SP地址PUSHSI;保护寄存器SISUBAX,AX;AX清零MOVCX,5MOVSI,BP+6;SI为C主程序调用时第一个实参在堆栈中的地址GOON:ADDAL,SI;把SI所指向的参数累加到AL中ADCAH,0;考虑进位INCSIINCSILOOPGOONPOPSI;恢复寄存器POPBPRET;返回,子程序最后一条语句必须是它WEEKPAYENDPEND,2020/6/9,关于被调用函数的返回值,一般按照下列规则传递给调用者:若返回值不超过16位,则由AX寄存器来传递,上例就是用这种方法实现的;若返回值超过16位但不超过32位,则由AX存放低16位,DX存放高16位来传递;若返回值

温馨提示

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

评论

0/150

提交评论