《汇编语言第9周-高级汇编.ppt》由会员分享,可在线阅读,更多相关《汇编语言第9周-高级汇编.ppt(56页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、汇编语言程序设计主讲:江苏苏主讲:江苏苏第9周 大课本周 主要内容 宏汇编与宏指令 高级汇编伪指令*重复汇编 条件汇编 汇编控制语句*汇编语言和C/C+语言混合编程*C语言程序的汇编输出 多模块程序设计的基本方法 程序库的建立汇编语言程序设计2汇编语言程序设计4宏汇编、重复汇编、条件汇编 统称宏结构宏(Macro)是汇编语言的一个特点,它是与子程序类似又独具特色的另一种简化源程序的方法。宏(宏定义)具有宏名的一段汇编语句序列宏定义时书写宏指令宏名作为一条指令直接使用,相当于宏定义体的缩写宏调用时书写宏展开汇编时用宏体代替宏指令的过程宏汇编时实现宏汇编的概念汇编语言程序设计5MACRO和ENDM
2、是二个必须成对出现的关键字,它们分别表示宏定义的开始和结束;MACRO和ENDM之间的部分是宏的定义体,它是由指令、伪指令或引用其它宏所组成的程序片段,是宏所包含的具体内容“宏名”是由程序员指定的一个合法的标识符,它代表该宏宏名可以与指令助忆符、伪指令名相同。在这种情况下,宏指令优先,而同名的指令或伪指令都失效;此方法不提倡在ENDM的前面不要再写一次宏名,这与段或子程序定义的结束方式有所不同;在宏定义的首部可以列举若干个形式参数,每个参数之间要用逗号分隔。宏定义的格式宏名macro 形参表宏定义体endm汇编语言程序设计6宏定义例:mainbeginMACRO ;定义名为mainbegin的
3、宏,无参数mov ax,data;宏定义体mov ds,axENDM;宏定义结束mainendMACRO retnum;带有形参retnummov al,retnum;宏定义中使用参数mov ah,4chint 21hENDMdispmsg MACRO stringlea dx,offset stringmov ah,09hint 21hENDM宏注释符汇编语言程序设计7宏调用的格式宏名宏名 实参表实参表 msgdb this is a macro instruction.,$start:mainbegin;宏调用,建立DS内容dispmsg msg;宏调用,显示字符串mainend 0;宏调
4、用,返回DOSend start 宏调用的实质是在汇编过程中进行宏展开 宏展开的具体过程是:当汇编程序扫描源程序遇到已有定义的宏调用时,即用相应的宏定义体取代源程序的宏指令,同时用位置匹配的实参取代形参汇编语言程序设计8宏展开在汇编时,用宏定义体的代码序列替代宏指令的过程。start:mainbegin;宏指令 1mov ax,data;宏展开 1mov ds,axdispmsg msg;宏指令 1 lea dx,offset string;宏展开 1mov ah,09h 1int 21hmainend 0;宏指令 1mov al,0;宏展开 1mov ah,4ch 1int 21h汇编语言程
5、序设计9 宏定义例 shlextmacro shlreg,shlnumpush cxmov cl,shlnumshl shlreg,clpop cxendm 宏指令shlext ax,6 宏展开 1push cx 1mov cl,06 1shl ax,cl 1pop cx灵活使用宏的参数-1宏定义时,参数可以是常数、变量、存储单元、指令(操作码)或它们的一部分,也可以是表达式;宏定义体可以是任何合法的汇编语句,既可以是硬指令序列,又可以是伪指令序列。汇编语言程序设计13与宏有关的伪指令局部标号伪指令LOCAL 标号列表宏定义体采用了标号,应使用LOCAL加以说明它必须是宏定义MACRO语句之后
6、的第一条语句宏展开时会按顺序自动生成唯一的序号式标号宏定义删除伪指令PURGE 宏名表当不需要某个宏定义时,可以把它删除;该指令后相关宏定义不再起作用中止宏扩展/宏定义退出伪指令EXITM遇到伪指令EXITM表示结束当前宏调用的展开转移伪指令GOTO标号;用于实现宏定义体内的转移功能,标号:;标号后不能写指令,但可写注释 汇编语言程序设计14;宏定义absolmacro oprdlocal nextcmp oprd,0jge nextneg oprdnext:endm;有二条宏调用absol word ptr bxabsol bx;宏展开1 1cmp word ptr bx,0 1jge?00
7、00 1neg word ptr bx 1?0000:;宏展开2 1cmp bx,0 1jge?0001 1neg bx 1?0001:必须独占一行局部标号伪指令例:汇编语言程序设计15宏与子程序的不同LOCAL在子程序中用于说明局部变量,在不同的子程序调用中,局部变量名不会改变;LOCAL在宏定义中用于说明局部标号,在不同的宏展开中,标号由唯一的序号替代。子程序的工作方式是每次调用执行相同的目标代码段;宏调用的工作方式是每次调用会生成相关的汇编源语句,汇编程序再将它们翻译成位于多处的目标代码段。子程序的参数通过变量或堆栈传递,子程序在调用后还必须返回,因而执行时要花较多的时间;宏的参数通过实
8、参替换形参来传递,参数形式多样,宏调用不需要返回。汇编语言程序设计16比较仅是源程序级的简化:宏调用在汇编时进行程序语句的展开,不需要返回;不减小目标程序,执行速度没有改变通过形参、实参结合实现参数传递,简捷直观、灵活多变还是目标程序级的简化:子程序调用在执行时由CALL指令转向、RET指令返回;形成的目标代码较短,执行速度减慢需要利用寄存器、存储单元或堆栈等传递参数宏子程序宏与子程序具有各自的特点,程序员应该根据具体问题选择使用当程序段较短或要求较快执行时,应选用宏;当程序段较长或为减小目标代码时,要选用子程序高级汇编伪指令 重复汇编重复汇编 条件汇编条件汇编 汇编控制语句汇编控制语句*汇编
9、语言程序设计18 这些伪指令会因汇编程序版本的不同而有不同的形式和规则。汇编语言程序设计19重复汇编重复汇编指在汇编过程中,重复展开一段(基本)相同的语句重复汇编没有名字,不能被调用重复汇编常用在宏定义体中,也可以在一般汇编语句中使用重复汇编伪指令有三个:REPEAT按参数值重复FOR按参数个数重复FORC按参数的字符个数重复最后,均用ENDM结束或MASM5.0对应写成REPTIRPIRPC汇编语言程序设计20按参数值重复REPEAT 重复次数 重复体ENDMchar=Achar=AREPEAT 26REPEAT 26 db char db char char=char+1 char=cha
10、r+1ENDMENDM 1db char;等效于db A 1char=char+1 1db char;等效于db B 1char=char+1.1db char;等效于db Z 1char=char+1汇编后汇编语言程序设计21按参数个数重复FOR FOR 形参形参,实参表实参表 重复体重复体ENDMENDMFOR regad,FOR regad,push regad push regadENDMENDM 1push ax 1push bx 1push cx 1push dx汇编后汇编语言程序设计22按参数字符个数重复FORC 形参,字符串 重复体ENDMFORC regad,dcbaFORC
11、 regad,dcba pop®ad&x pop®ad&xENDMENDM 1pop dx 1pop cx 1pop bx 1pop ax汇编后汇编语言程序设计23条件汇编条件汇编伪指令在汇编过程中,根据条件决定汇编的语句IFxx 表达式;满足,汇编分支语句体1分支语句体1 ELSE;不满足,汇编分支语句体2分支语句体2 ENDIF;条件汇编结束汇编语言程序设计24伪指令含义IF exp若数值表达式exp的值不为0,则语句组1包含在目标文件中IFE exp若数值表达式exp的值为0,则语句组1包含在目标文件中IFDEF symb若符号symb有定义或被说明为EXTRN,则语句组1包
12、含在目标文件中IFNDEF symb若符号symb没有定义,也没被说明为EXTRN,则语句组1包含在目标文件中IFB 在宏引用时,若该形参没有相应的实参相对应,则语句组1包含在目标文件中IFNB 在宏引用时,若该形参有相应的实参相对应,则语句组1包含在目标文件中IFIDN,若参数1参数2,则语句组1包含在目标文件中IFDIF,若参数1参数2,则语句组1包含在目标文件中IF1若汇编程序在第一遍扫描时,则语句组1包含在目标文件中IF2若汇编程序在第二遍扫描时,则语句组1包含在目标文件中汇编语言程序设计25pdatamacro num IF num lt 100;如果num 100,则汇编如下语句d
13、b num dup(?)ELSE;否则,汇编如下语句db 100 dup(?)ENDIFendmpdata 12 ;宏调用db 12 dup(?);宏汇编结果pdata 102 ;宏调用db 100 dup(?);宏汇编结果条件汇编例:汇编语言程序设计31MASM6.0以后引入的高级语言程序设计特性条件控制伪指令.IF .ELSE .ENDIF循环控制伪指令.WHILE .ENDW .REPEAT .UNTIL过程声明和过程调用伪指令.PROTO .INVOKE汇编语言程序设计32汇编控制:条件控制伪指令 类似高级语言中IF-THEN-ELSE结构语句的相应功能在汇编时将展开,自动生成相应的比
14、较和条件转移指令序列,实现程序分支条件操作符格式1:.IF condition 指令序列.ENDIF格式2:.IF condition 指令序列1;condition条件成立时执行.ELSE 指令序列2;condition条件不成立时执行.ENDIF格式3:.IF condition1 指令序列1.ELSEIF condition2 指令序列2.ENDIF汇编语言程序设计34单分支结构:.IF ax=0 add ax,bx .else .break .endif inc bx inc bx.untilcxzmov result,ax例:累加array数组中的正数汇编语言程序设计38调用带较多参
15、数定义的过程时,可不采用CALL指令,因为比较烦琐可采用过程调用伪指令INVOKE使用INVOKE伪指令的前提是需要用PROTO伪指令对过程进行声明过程声明和过程调用伪指令过程名PROC调用距离 语言类型 作用范围 入口宏USES 寄存器列表,参数:类型LOCAL 参数表;汇编语言语句过程名ENDP过程声明伪指令:用于事先声明过程的结构过程名 PROTO 调用距离 语言类型,参数:类型过程调用伪指令 INVOKE 过程名,参数,.汇编语言程序设计39.model small checksumd PROTO c:word,a:word;声明过程.stack.dataarraydb 12h,25h
16、,0f0h,0a3h,3db 68h,71h,0cah,0ffh,90hcountequ$-array;数组的元素个数resultdb?;校验和.code.startup INVOKE checksumd,count,offset array ;调用过程mov result,al;保存校验和.exit 0列表文件例:数组求和的汇编语言源程序-1/2汇编语言程序设计40checksumd PROC c USES bx cx,countp:word,arrayp:wordmov bx,arrayp;BX数组的偏移地址mov cx,countp;CX数组的元素个数xor al,alsumd:add
17、al,bx;求和:ALAL+DS:BXinc bxloop sumdretchecksumd endpend列表文件例:数组求和的汇编语言源程序2/2汇编语言程序设计41.INVOKE checksumd,count,offset array*mov ax,word ptr OFFSET array*push ax*mov ax,+000Ah*push ax*call checksumd*add sp,04hmov result,al.指示该语句由汇编程序自动生成例:数组求和程序的汇编列表-1/2汇编语言程序设计42checksumd PROC c USES bx cx,countp:word
18、,arrayp:word*push bp;起始代码*mov bp,sp*push bx;保护bx和cx*push cxmov bx,arrayp;arrayp=BP+6mov cx,countp;countp=BP+4.ret*pop cx;结尾代码*pop bx*pop bp*ret 0000hchecksumc endp例:数组求和程序的汇编列表-2/2补充内容*:汇编语言和C/C+语言混合编程 C语言程序的汇编输出 多模块程序设计的基本方法 程序库的建立汇编语言程序设计43汇编语言与C/C+语言的混合编程汇编语言程序设计44格式1:单条指令 _asm 助记符 操作数 ;单句汇编语言指令格
19、式2:指令序列_asm ;汇编语言指令序列 单条汇编语言指令:_asm mov ax,1a69h_asm mov dx,378h_asm out dx,ax指令序列例:_asm mov ax,1a69h mov dx,378h out dx,ax 汇编语言与C/C+语言的混合编程汇编语言程序设计45说明:在嵌入的汇编语言指令中,可以使用C/C+语言的数据格式。例如,1a69h可以书写为0 x1a69。嵌入的汇编语言代码不能使用MASM的伪指令来定义数据。在嵌入的汇编语言代码中,不需要保护寄存器EAX、EBX、ECX、EDX、ESI和EDI的值,必要时由C/C+编译器负责生成保护指令。需要保护寄
20、存器DS、SS、ESP、EBP以及方向标志DF的值。嵌入的汇编语言指令,除了可以使用立即数与寄存器外,还可以使用C/C+程序中定义的标识符,如常量、变量、标号、函数名与函数参数等。C/C+编译器自动将它们转换成相应汇编语言指令的操作数,并在标识符前自动加下划线。C/C+程序调用汇编语言过程汇编语言程序设计46调用约定 包括_cdecl和_stdcall两种:C/C+函数缺省采用_cdecl调用约定,这种约定在函数名前自动加一个下划线,从右到左将实在参数压入堆栈,由函数的调用者负责堆栈的平衡:_函数名 Win32 API函数采用_stdcall调用约定,这种约定从右到左将实在参数压入堆栈,由函数
21、本身负责移去调用者压入堆栈的参数,函数名在编译后被转换为如下形式:_函数名参数长度 其中,参数长度是指参数表的字节数(十进制)。例如,设函数fun有两个32位参数,则供外部模块调用的名称为 _fun8 C/C+程序调用汇编语言过程汇编语言程序设计47声明约定 在Microsoft Visual C+中,需要用extern C对所要调用的外部过程、函数和变量予以声明。形式:extern C 返回值类型 调用约定 函数名(形式参数表);extern C 变量类型 变量名;在用汇编语言编写的程序中,必须用public声明供外部模块使用的标识符:PUBLIC标识符1,标识符2,不同语言编写的程序模块分
22、别进行汇编或编译,最后把所有的目标文件连接在一起。C语言程序的汇编输出*汇编语言程序设计48 在Turbo C+或Borland C+编程环境下,可用TCC或BCC行命令把一个C语言的源程序转换成汇编语言的源程序。C语言程序清单:#include int sum(int a,int b,int c)return(a+b+c);void main()int a,b,c;a=b=12;c=32;printf(%d,sum(a,b,c);_TEXTsegment byte public CODE ;代码段语句_TEXTends _DATA segmentwordpublic DATA ;数据段的定义
23、_DATAends;下面说明函数的属性public _main end汇编语言的详细清单:汇编语言程序设计49多模块程序设计 多模块程序的组织 源文件级的连接:使用INCLUDE 缺点:由于合并后的源文件为一个汇编单位,源文件与被包含文件的标识符不能重复。目标文件级的连接:各模块单独汇编。常用的方法:二者结合。根据功能的相对独立性,将整个程序分为若干个.ASM文件,单独编写;将公共的常量定义、宏定义、外部过程声明等组织在一个或多个.INC文件中;.ASM文件根据需要使用INCLUDE。汇编语言程序设计50多模块程序开发的基本步骤 模块的划分;编写源程序;按模块组织成.ASM文件;汇编:将每个.
24、ASM文件分别汇编为.OBJ文件;将所有.OBJ文件连接为一个完整的.EXE文件。多模块程序设计 汇编语言程序设计51多模块间的通信 通过公共标识符的定义和引用,外部过程的参数传递等来实现。1.PUBLIC伪指令 PUBLIC 标识符,标识符表示这些标识符是本模块定义的、可被外部模块引用的公共标识符,可以是变量名、标号、过程名以及由EQU(或=)定义的符号名。2.EXTRN伪指令 EXTRN 标识符:类型,标识符:类型 表示这些标识符是外部模块定义、本模块要引用的外部标识符,主要类型包括:NEAR和FAR(用于过程)。BYTE、WORD、DWORD等(用于变量)。多模块程序设计 汇编语言程序设
25、计52 Make文件的使用 make文件是一个文本文件,用来描述文件之间的依赖关系。make文件由依赖语句和处理该依赖的命令组成。依赖语句的形式如下:目标:依赖文件 若依赖文件已发生变化,则执行依赖语句后面的命令。例如:pgm.exe:pgm1.obj pgm2.objml/Fe pgm.exe pgm1.obj pgm2.obj 表示pgm.exe依赖于pgm1.obj与pgm2.obj,只要pgm1.obj或pgm2.obj发生任何变化,均应重新建立pgm.exe文件。多模块程序设计 汇编语言程序设计53子程序库 C/C+语言的程序设计环境提供了大量库文件,库文件中包含了大量的标准函数或过
26、程。用户可以创建自己的库文件。库文件可以看成是子程序的集合。库文件中存储着子程序名、子程序的目标代码以及连接所需要的重定位信息。当某目标文件与库文件相连接时,LINK程序只把目标文件所用到的子程序从库文件中找出来,并合并到最终的可执行文件中,而不是把库中所含的全部子程序都纳入最后的可执行文件。汇编语言程序设计54建立库文件命令LIB MS-DOS系统中显示命令LIB的用法:lib/?Windows系统中显示命令LIB的用法:D:MASM611BINLIB/?汇编语言程序设计551)各选项的解释选项含义/?、/HELP显示LIB命令的用法,描述各命令行参数的含义/IGNORECASE忽略子程序名
27、中的大小写在实践中,作用不明显/NOIGNORECASE不忽略子程序名中的大小写/NOEXTDICTIONARY 不建立扩展的目录/NOLOGO不显示版本号和版权信息/PAGESIZE:n设置库文件的每页字节数为n2)命令项的解释:选项含义+name向库文件中加一个新的目标文件-name从库文件中删除一个指定的目标文件-+name用新的目标文件替换掉库文件中原有的目标文件*name拷贝出指定的目标文件-*name从库文件中移出指定的目标文件汇编语言程序设计56建立库文件举例 假设现有目标文件sub1.obj、sub2.obj和sub3.obj,要用它们建立库文件mylib.lib。方法1:把所有目标文件一次性加入到库文件中lib mylib+sub1+sub2+sub3方法2:随着目标文件的逐个生成,而依次加入到库文件中lib mylib+sub1lib mylib+sub2lib mylib+sub3假如源文件sub3.asm已修改,并也生成了新的目标文件sub3.obj,这时,就需要把库文件mylib.lib中的sub3.obj替换成新的目标文件。可用下面命令来实现替换:lib mylib -+sub3