




已阅读5页,还剩21页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Intel汇编语言程序设计程序模板TITLE Program Template(Template.asm);编译器忽视TITLE的一行;程序描述注释信息;作者;创建日期;修改者;修改日期include Irvine32.inc包含一些常量定义,函数声明includelib kernel32.dll包含函数定义的导入库.data;在此插入变量.codemain PROC;伪指令,标识一个程序的开始指令;在此插入可执行代码call sample;调用子程序(过程)exit;调用Irvine32.inc中的命令,结束程序main ENDP;伪指令,标识一个程序的结束sample PROC;子程序(过程)指令;在此插入可执行代码retsample ENDPEND main;伪指令,标识所有程序的结束,后跟程序入口点注意:1. 单行注释:以分号(;)字符开始,汇编器忽视分号后所有字符2. IA-32处理器从偶数双字地址处加载代码和数据更快速3. NOP 空操作(配合第二条).stack 4096;在运行时栈上保留4096字节的空间x86的寄存器32位通用寄存器EAX在乘法和除法指令中被自动使用AXAH|ALEBXBXBH|BLECX在某些指令中作为循环记数器CXCH|CLEDXDXDH|DLEBPBPESPSP栈指针ESISI用于数据传递EDIDI用于数据传递EFLAGSEIP指令指针16位段寄存器CSSSDSESFSGSEFLAGS控制标志CF进位标志OF溢出标志SF符号标志ZF零标志AC辅助进位标志PF奇偶标志系统寄存器浮点寄存器参数可选参数参数1|参数2必须任选一个参数参数1|参数2参数1,参数2任选其一,作为可选参数标号命名规则1. 标号可包含1247个字符2. 标号大小写不敏感3. 标号第一个字符必须是字母,_(下划线),?或$4. 标号第二个字母以后可以有数字5. 标号不能与保留字相同6. 尽量避免用/_作为首字母数据定义变量名数据定义伪指令 初始值,初始值例:val1 byte 1,2,3,4数据定义伪指令(数据类型)BYTE/SBYTE1字节整数(无符号/有符号)WORD/SWORD2字节整数(无符号/有符号)DWORD/SDWORD4字节整数(无符号/有符号)FWORD6字节整数QWORD8字节整数TBYTE10字节整数REAL44字节短实数REAL88字节长实数REAL1010字节扩展精度实数PTR XXXX(例如BYTE)4字节指针,指向一个指定类型的地址例:value1 BYTE A定义一个byte,值为A,变量名为value1value2 WORD ?定义一个未初始化的word,变量名为value2list byte 10,20,30,40定义4个byte,值为10,20,30,40,变量名位listgreeting1 BYTE “1234”,0dh,0ah定义6个byte,值为1,2,3,4,dh,ah变量名位greeting注意:16进制数以字符开始时,前面加0. 0dh,0ah为回车换行符DUPBYTE 20 DUP (0)定义20个BYTE,值都为0BYTE 2 DUP (“AB”)定义4个BYTE,值为”ABAB”.data?BYTE 1000 DUP(?)比.dataBYTE 1000 DUP(?)更有效率,更节省空间定义实数(p63)“=”伪指令与TEXTEQU可以在同一源文件中重新定义,EQU不可以重新定义count = 500此句不占内存mov ax,count等同于mov ax,500list BYTE 10,20,30ListSize = ($ - list)自动计算list的数据长度,不占内存$表示当前地址的值在循环语句块中,$表示第一个节点的地址值M1 EQU 10 * 10此句不占内存word M1等同于word 100M2 EQU 此句不占内存byte M2等同于byte “12345”M3 EQU 10+10mov ax,M3*10AX=200M4 EQU mov ax,M4*10AX=110M5 EQU M1此句不占内存mov ax,M5等同于mov ax,100TI TEXTEQU %(M3 * 2)%展开操作符,返回40(作为文本)MOV ax,T1等同于mov ax,40MOVE TEXTEQU MOVE eax,T1等同于mov eax,40操作数类型r8 r16 r328位/16位/32位通用寄存器reg通用寄存器sreg16位段寄存器(6个)imm立即数mem内存操作数imm8 imm16 imm328位/16位/32位立即数r/m8 8位操作数(可以是通用寄存器或内存操作数)r/m16 r/m3216位操作数/32位操作数mov 目的操作数,源操作数目的操作数源操作数regreg/mem/immmemreg/immr/m16sregsregr/m16注意:1.尺寸必须一样2.不能同时为内存操作数3.目的操作数不能为CS/EIP/IP4.立即数不能直接送至段寄存器mov eax,ebxeax=ebxmovzx ax,bl位数不够补0,相当于al=bl ah=0movsx ax,bl位数不够补0/1,看bl的最高位,是1补1,是0补0lahf把EFLAGS的低8位保存到AH中sahf把AH中的数据存入EFLAGS的低8位中xchg ax,bx交换ax和bx的值inc axax=ax+1dec axax=ax-1影响标志位:零标志,符号标志,溢出标志,辅助进位标志,奇偶标志add/sub 目的操作数,源操作数add eax,ebxeax=eax+ebxsub eax,ebxeax=eax-ebx影响标志位:进位标志,零标志,符号标志,溢出标志,辅助进位标志和奇偶标志adc/sbb 目的操作数,源操作数adc eax,ebxeax=eax+ebx+CFsbb eax,ebxeax=eax-ebx-CFneg axax=-ax影响标志位:进位标志,零标志,符号标志,溢出标志,辅助进位标志和奇偶标志对非0操作数执行NEG操作总是设置进位标志offset 标号返回标号的偏移地址myArray word 1,2,3,4,5mov esi,offset myArray + 4esi=myArray的偏移地址+4align 1|2|4|8|16变量地址的对其方法val1 byte ?假设偏移地址是:00404000align 2val2 byte ?偏移地址是:00404002地址为2的倍数val3 byte ?偏移地址是:00404003对其的好处:CPU处理存储在偶数地址处的数据要比存储在奇数地址处的数据快mydouble dword 12345678hmov ax,word ptr mydoubleax=5678hptr重载变量尺寸val1 label wordval2 dword 12345678hmov ax,val1ax=5678hlabel为val2起了一个别名,不占内存type 变量返回单个变量的大小val1 dword ?mov ax,type val1 ax=4lengthof 变量返回变量所在的一行的元素个数val1 word 1,2,3,4,5mov ax, lengthof val1ax=5sizeof 变量返回变量的总大小val1 word 1,2,3,4,5smov ax,sizeof val1ax=10val2 dword val1指向val1的地址的指针变量val2mov esi,val2esi=va1的地址mov ax,esiax= 1(val1的值)pbyte typedef ptr byte给内建类型起别名,可用于创建指针变量(以区别内建类型)push r/m/imm32将操作数入栈push eax将eax寄存器的值入栈流程:入栈前ESP指向当前栈顶.入栈栈ESP先减4,然后将EAX的值存入ESP指向的地址中pop r/m/imm32将操作数出栈pop eax将eax寄存器的值出栈流程:入栈前ESP指向当前栈顶.入栈时先将ESP指向地址中的数据存入EAX中,然后ESP加4pushfd将EFLAGS寄存器的值压入栈中popfd将栈中的数据压入EFLAGS中pushad按EAX,ECX,EDX,EBX,ESP(执行pushad指令前的值),EBP,ESI,EDI顺序入栈popad按相反顺序回复寄存器的值call 标号将call后面指令的偏移地址入栈,然后跳转到标号处ret将栈中数据弹出并装入EIP中ret n将栈中数据弹出并装入EIP后,ESP+nuses 寄存器配合PROC指令用栈保护寄存器数据ArraySum PROC uses esi ecxArraySum PROC编译成mov esi,1push esi push ecxmov ecx,2mov esi,1 mov ecx,2pop ecxpop esiretretArraySum ENDPArraySum ENDPAND 目的操作数,源操作数mov al,00111011band al,00001111bal=00001011b,对应数据位按位”与”运算影响标志:符号标志,零标志,奇偶标志,溢出标志=0,进位标志=0OR 目的操作数,源操作数mov al,00111011or al,00001111al=00111111,对应数据位按位”或”运算影响标志:符号标志,零标志,奇偶标志,溢出标志=0,进位标志=0XOR 目的操作数,源操作数mov al,10110101bxor al,0al=10110101b,对应数据位按位”异或”影响标志:符号标志,零标志,奇偶标志,溢出标志=0,进位标志=0注意:1.同0异或的位保持不变,同1异或的位取反2.与同一操作数异或两次,值不变:(X异或Y)异或Y=Xmov ax,0110010011000001bxor ah,al用来判断16位奇偶值NOT reg/memmov al,11110000bnot alal=00001111b,对一个操作数的所有位取反影响标志位:无TEST目的操作数,源操作数mov al,00111011band al,00001111bal=00111011b,对应数据位按位”与”运算,但是不修改目的操作数影响标志位:符号标志,零标志,奇偶标志,溢出标志=0,进位标志=0CMP 目的操作数,源操作数mov ax,5cmp ax,10ax=5, 作ax10运算,影响标志寄存器,并不保存结果影响标志位:进位标志,零标志,符号标志,溢出标志,辅助进位标志和奇偶标志无符号数CMP的结果ZFCF目的源00目的=源10有符号数CMP的结果标志目的源SF=OF目的=源ZF=1设置和清除单个CPU状态test al,0of=1and al,0of=1or al,1of=0or al,80hsf=1and al,7Fhsf=0mov al,7fhinc alof=1or eax,0of=0stccf=1clccf=0jmp 标号无条件跳转到标号处开始执行命令条件跳转跳转指令 标号例:jz L1.L1:基于标识jz当ZF=1时跳转jnz当ZF=0时跳转jc当CF=1时跳转jnc当CF=0时跳转jo当OF=1时跳转jno当OF=0时跳转js当SF=1时跳转jns当SF=0时跳转jp当PF=1时跳转jnp当PF=0时跳转cmp lefop(左操作数),rightop(右操作数)je当leftop=rightop时跳转jne当leftoprightop时跳转jcxz当CX=0时跳转jecxz当ECX=0时跳转无符号的比较跳转指令ja当leftoprightop时跳转jnbe当leftoprightop时跳转jae当leftop=rightop时跳转jnb当leftop=rightop时跳转jb当leftoprightop时跳转jnae当leftoprightop时跳转jbe当leftop=rightop时跳转jna当leftoprightop时跳转jnle当leftoprightop时跳转jge当leftop=rightop时跳转jnl当leftop=rightop时跳转jl当leftoprightop时跳转jnge当leftoprightop时跳转jle当leftop=rightop时跳转jng当leftopexpr2当expr1大于 expr2时返回真expr1=expr2当expr1大于等于expr2时返回真expr1expr2当expr1小于expr2时返回真expr1ASC格式aas 把AL中两个ASC格式的数的差转化为未压缩格式mov ah,0mov al,8AX=0038Hsub al,9AX=00FFHaasAX=FF09Hor al,30hAX=FF39H未压缩格式-ASC格式aam指令把两个未压缩格式的数的乘积转化为未压缩格式存入AH(十位),AL(个位)中mov al,05hmov bl,06hmul blAX=001EHaamAX=0300H(03和00表示30)aad指令把两个未压缩格式的数转化为二进制数mov ax,0307hAX=0307H(03和07标志37)aadAX=0025H=37压缩格式指令每个十进制用4个数据位储存val1 byte 34h表示34val2 word 0237h表示237daa指令把两个压缩格式的数的和重新转化为压缩格式存入AL的高半部分(十位),低半部分(个位)中mov al,35hadd al,48hAL=7DHdaaAL=83Hdasmov al,85hsub al,48hAL=3DHdasAL=37H(表示37)lea esi,ebp-30把ebp-30代表的地址赋予esi与offset区别:因为offset是伪指令,所以offset在编译时完成赋值,offset不能取像ebp这种可以动态变化的值.lea是指令,所以lea可以取到动态的地址,比如局部变量的地址子程序运行时的栈结构invoke sub,参数2,参数1sub PROC,参数2:类型,参数1:类型,local 局部变量1:类型, 局部变量2:类型, 局部变量3:类型enter numbytes,nestinglevel创建一个程序的栈框架numbytes:为局部变量预留的地址(4的整数倍)nestinglevel:决定了从调用程序复制到当前栈框架中的栈框架指针的数目enter 0,0保护ebp并初始化ebp等价于push ebpmov ebp,espenter 8,0保护ebp并初始化ebp,然后esp-8为2个局部变量预留空间等价于push ebpmov ebp,espsub esp,8leave释放一个程序的栈框架等价于mov esp,ebppop ebplocal 标号:类型,标号:类型声明局部变量local temp:DWORD,flag:BYTEmov eax,temp编译后push ebpmov ebp,espadd esp,0fffffff8hESP=ESP-8mov eax,temp.model 内存模式,模式选项.model flat,STDCALL决定程序的模式是平坦模式(32位专用),STDCALL是对外接口语言关键字,决定参数从右至左入栈,返回时被调用的程序负责释放参数最后STDCALL把要导出的子程序名修改为:_namen例:_ADDTWO8name放名字,n放参数占的字节数(一个参数占4字节)C决定参数从右至左入栈,返回时调用程序负责释放参数invoke 子程序名,参数列表参数入栈顺序由.MODEL指定invoke dumpArray,offset array,lengthof array,type array编译后push type arraypush lengthof arraypush offset arraycall dumpArray注意:invoke只会把4字节数据入栈,2字节数据处理方法:sub esp,2 push word ptr 数据1字节数据处理方法:mov al,数据 push eax所以invoke 伪指令可能会修改EAX或EDX的值,可以提前保存ADDR取参数偏移地址invoke dumpArray,addr array(全局变量)invoke dumpArray,addr array(局部变量)编译成编译成push offset arraylea eax,arraycall dumpArraypush eaxcall dumpArray注意:1.只能配合invoke伪指令,例:invoke dumpArray,addr array2.传递的参数必须是常量(不可以动态改变)3.此常量必须在invoke之前声明或定义4.array是offset和lea的二合一PROC标号 PROC 属性 USES 寄存器列表,参数列表属性:distance|langtype|visibility|prologuelangtype语言类型:如C,STDCALL等参数列表注意第一个参数前面也有逗号例:参数1:类型,参数2:类型addTwo procval1:dwordval2:dwordmov eax,val1add eax,val2retaddTwo endp编译后addTwo procpush ebpmov ebp,espmov eax,dword ptr ebp+8因为invoke时是从右至左入栈,所以val1=ebp+8add eax, dword ptr ebp+12leave等价于mov esp,ebp pop ebpret 8弹出两个参数所以是8字节addTwo endpPROTO声明一个子程序(过程)1. 把PROC完全复制到程序开始2. 去掉”USES 寄存器”部分并把PROC改为PROTOmySub PROC PRIVATE隐藏模块内的mySub子程序mySub PROC PUBLIC 显示模块内的mySub子程序option PROC:PRIVATE放在程序开头,隐藏模块内所有子程序PUBLIC mysub,子程序名指定要导出的子程序PUBLIC 变量名导出指定变量(变量默认私有)EXTERN 子程序名栈参数大小:PROC例:被调用程序的文件:addTwo.asmaddTwo procval1:dwordval2:dword.addTwo endp调用程序的文件:main.asmextern addTwo8:PROC.codecall addTwo8如果call改为invoke,则被调用程序的文件:addTwo.asm不变调用程序的文件:main.asmaddTwo PROTO.codeinvoke addTwo或者声明文件sum.incaddTwo PROTO被调用程序的文件:addTwo.asminclude sum.inc.codeaddTwo procval1:dwordval2:dword.addTwo endp调用文件:main.asminclude sum.inc.codeinvoke addTwoEXTERN 变量名:类型(以EQU和”=”定义的,类型是ABS)INCLUDE var.inc配合EXTERNDEF在var.inc中externdef 变量名:类型在sub1.asm中include var.inc变量名 类型 数据在main.asm中include var.inc可以直接使用该变量rep当ECX0时重复repz/repe当ECX0且ZF=1时重复repnz/repne当ECX0且ZF=0时重复注意下面命令执行完后会自增或自减movsb把ESI指向的内存中的数据按字节复制到EDI中,然后ESI,EDI自增或自减mov edi,esimovsw按字复制movsd按双字复制cmpsb比较ESI和EDI指向的字节内存数据的值,然后ESI,EDI自增或自减cmp esi,edicmpsw比较字内存数据cmpsd比较双字内存数据scasb比较AL与EDI指向的字节内存数据,然后EDI自增或自减scasw比较AX的值scasd比较EAX的值stosb把AL的值存入EDI指向的字节内存数据中,然后EDI自增或自减stosw把AX的值存入stosd吧EAX的值存入lodsb把ESI指向的字节内存数据存入AL中,然后ESI自增或自减lodsw存入AX中lodsd存入EAX中结构名 STRUCT定义结构域声明结构名 ENDS例Employee STRUCTId byte “000000000”;默认值LastName byte 30 dup (?);默认值未定义align 2;域中变量注意对其Years word 0SalaryHistory dword 0,0,0,0Employee ENDS变量名 结构名 定义结构变量或: 变量名 结构名 初始值列表align dword按结构中最大尺寸类型对其变量worker Employee 用默认值初始化结构person1 Employee 只初始化Idperson2 Employee 跳过Id,初始化lastNameperson3 Employee 跳过前面全部,初始化SalaryHistorypersonArray Employee 5 dup()定义一个包含5个Employee结构的数组变量引用变量中的域mov ax,worker.Years引用结构变量中的域mov ax,( Employee ptr esi).Years引用结构变量中的域联合名 UNION定义联合域声明联合名 ENDS或结构名 STRUCT域声明UNION 联合名域声明ENDS结构名 ENDS例:Integer uniond dword 0w word 0b byte 0Integer ends注意:联合使用预设值时,所有域的预设值应保持一致宏名 MACRO参数1,参数2.定义一个宏(宏过程)指令ENDM注意:定义宏时注明不能作宏参数的寄存器(因为在宏中修改寄存器的数值可能会导致赋值错误)PrintX Macro char:=宏定义时给参数设置默认值mov al,charcall WriteCharEndm宏名 参数1,参数2.调用宏PrintX调用定义好的PrintX注意:调用的参数数量可以少于定义,但是顺序不能不同被替换为mov al,Xcall WriteCharmakeString MACRO TEXTLOCAL string多次调用宏,string会出现重名,Local会把标号重定义为”?nnnn”.datastring byte TEXT,0参数TEXT会替换此处的TEXTENDMmakestring “Hello”调用宏makestring,注意本例子hello有引号宏名 MACRO参数1:REQREQ指定宏参数是必须的指令;宏注释必须是两个分号ENDM宏名 MACRO参数1ECHO This is a example;ECHO在预处理时显示后面的语句(运行时不显示)ENDMmWriteLn MACRO textmWrite text宏mWriteLn的参数text直接传递给宏mWrite指令ENDM条件汇编指令IF condition指令ELSE指令ENDIF常量布尔表达式LT小于GT大于EQ等于NE不等于LE小于等于GE大于等于例IF (X LT 0) OR (X GT 79)指令ENDIF与.IF区别: .IF是运行时伪指令,在运行时求值,IF是条件汇编伪指令,在编译时求值IF 表达式表达式为真则允许汇编IFB 参数为空则允许汇编IFNB 参数不为空则允许汇编IFIDN ,两个参数相同则允许汇编,大小写敏感IFIDNI ,两个参数相同则允许汇编,大小写不敏感IFDIF ,两个参数不同则允许汇编,大小写敏感IFDIFI ,两个参数相同则允许汇编,大小写不敏感IFDEF 名字如果名字已经定义则允许汇编IFNDEF 名字如果名字没有定义则允许汇编ENDIF结束一个条件汇编伪指令开始的语句块ELSE如果前面条件均为假,则允许汇编ELSEIF 表达式如果前面条件均为假,当前表达式为真,则允许汇编EXITM立即退出宏,阻止其后任何语句的展开例:mWriteStr macro stringIFB 如果string参数为空,返回真ECHO Error:.EXITMENDIFENDMmRead macro maxcharsIFIDNI ,如果maxchars是EDX,返回真指令ENDIFENDM替换操作符(&)mShowRegister macro regName.datatemp byte “®Name=”,0&强制预处理实际传递的宏参数.ENDMmShowRegister EDX显示的是EDX=,否则显示的是regName=展开操作符(%)mGotoXY %(5*10)表达式首先被计算求值然后传递给宏.dataarray dword 1,2,3,4.codeECHO The array contains %(sizeof array) bytes显示的The array contains %(sizeof array) bytes改为TEMP TEXTEQU %(sizeof array)% ECHO The array contains TEMP bytes显示The array contains 16 bytesLINe 返回当前源代码的行号文本操作符()mWrite macro char指令ENDMmWrite “Line three”,0dh,0ah会被当成3个参数mWrite 会被当成1个参数特殊文本字
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论