您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 其它行业文档 > 11第三章Intel处理器指令系统及汇编语言_1.
1例:.dataarrayBBYTE10h,20h,30h.codemovesi,0moval,[arrayB+esi];?moval,arrayB[esi];?movesi,OFFSETarrayBmoval,[esi];?moval,[esi+1];?moval,[esi+2];?Array定义为word?3.寄存器(相对)寻址/基址寻址/变址寻址AL=10h同上,另一种格式AL=10hAL=20hAL=30h2地址可以使用任意两个通用寄存器的组合movedi,[ebx+esi]movedi,[ebx][esi];基址变址寻址,功能:EDI=DS:[EBX+ESI]moveax,[ebx+edx+80h]moveax,80h[ebx+edx]moveax,80h[ebx][edx];相对基址变址寻址功能:EAX=DS:[EBX+EDX+80H]3.(带位移量的)基址变址寻址3带位移量的基址比例因子变址寄存器乘以2,4或8比例1、2、4和8对应8、16、32和64位数据的字节个数,便于以数组元素为单位寻址相应数据moveax,[ebx*4];带比例的基址寻址moveax,[esi*2+80h];带比例的相对变址寻址moveax,[ebx+esi*4];带比例的基址变址寻址moveax,[ebx+esi*8-80h];带比例的相对基址变址寻址ESP寄存器不能乘以比例系数4INCLUDEIrvine32.inc.datacountdword12345678h,9abcdef0h,0,0,3721h.codestart:movebx,offsetcount;EBX=count变量的有效地址(立即数寻址)movesi,0movecx,lengthofcountK1:moveax,[ebx+esi*4]incesiloopk1movesi,0movecx,lengthofcountK2:moveax,count[esi*4]incesiloopk2exitendstart5控制转移或分支是一种改变程序执行顺序的方法。控制转移可分为两种:无条件转移:以JMP指令为例条件转移:以LOOP指令为例(五)JMP和LOOP指令6例:创建一个循环top:...jmptop;死循环(五)JMP和LOOP指令1.JMP指令7格式:LOOP目的地址/标号执行过程:在实地址模式下,用做默认循环计数器的是CX而不是ECX。在任何模式下,LOOPD指令都使用ECX作为循环计数器;LOOPW都使用CX作为循环计数器。(五)JMP和LOOP指令2.LOOP指令ECX←ECX-1ECX=0?N目的地址Y8例:movax,0movecx,5L1:incaxloopL1循环结束时,AX=?ECX=?(五)JMP和LOOP指令2.LOOP指令509循环的目的地址与当前地址只能在相距-128到+127字节的范围之内。机器指令平均3字节左右,因此一个循环平均最多只能包含大约42条指令。循环的嵌套(五)JMP和LOOP指令2.LOOP指令.datacountDWORD?.codemovecx,100L1:movcount,ecxmovecx,20L2:..loopL2movecx,countloopL110数组元素的求和(SumArray.asm);Thisprogramsumsanarrayofwords.INCLUDEIrvine32.inc.dataintarrayWORD100h,200h,300h,400h.codemainPROCmovedi,OFFSETintarray;addressofintarraymovecx,LENGTHOFintarray;loopcountermovax,0;zerotheaccumulatorL1:addax,[edi];addanintegeraddedi,TYPEintarray;pointtonextintegerloopL1;repeatuntilECX=0INVOKEExitProcess,0mainENDPENDmain(五)JMP和LOOP指令3.例子:整数数组求和11TITLECopyingaString(CopyStr.asm);Thisprogramcopiesastring.INCLUDEIrvine32.inc.datasourceBYTEThisisthesourcestring,0targetBYTESIZEOFsourceDUP(0),0.codemainPROCmovesi,0;indexregistermovecx,SIZEOFsource;loopcounterL1:moval,source[esi];getacharacterfromsourcemovtarget[esi],al;storeitinthetargetincesi;movetonextcharacterloopL1;repeatforentirestringINVOKEExitProcess,0mainENDPENDmain(五)JMP和LOOP指令4.例子:拷贝字符串微机原理及接口技术第3章Intel处理器指令系统及汇编语言四、堆栈、过程13本节要点外部库链接静态/动态库堆栈过程随着程序规模的增长,需要对其进行适当的划分14链接库:已经编译好的子程序库过程(子程序)用户怎样使用?假设程序要调用名为WriteString的过程在控制台上显示字符串WriteString是一个已经编译好的子程序(一)与外部库链接背景知识编译目标文件库插入15用户使用步骤1.程序开始部分用PROTO声明子程序WriteStringPROTO2.程序中用CALL指令调用callWriteString3.当程序被编译时,编译器为CALL指令的目标地址留出空白,该空白将由链接器填充。4.链接器在链接库中查找WriteString这个名字,从库中把合适的机器指令拷贝到程序的可执行文件中,并把WriteString的地址插入到CALL指令中。(一)与外部库链接背景知识16链接器的命令行选项Link32/subsystem:windowsHelloWin.objuser32.libkernel32.lib(一)与外部库链接背景知识你的程序链接到user32.libkernel32.lib运行user32.dllkernel32.dll运行kernel32.lib只是API函数的链接信息kernel32.dll包含实际的执行代码17堆栈是一段连续的内存空间遵循“后进先出”,或者“先进后出”的规则(二)堆栈操作1832位的压栈(PUSH)操作如PUSH0A5H堆栈指针ESP减4,ESP=ESP-4将进栈数据拷贝到堆栈指针所指向的位置。SS:[ESP]=srcpushr/m16pushr/m32pushimm32(二)堆栈操作1.堆栈:①压栈操作/推入堆栈ESP000000060000100000000FFC00000FF800000FF400000FF0压栈之前00000006000000A50000100000000FFC00000FF800000FF400000FF0ESP压栈之后ESP19出栈(POP)操作POPECX从当前栈顶(ESP指向的位置)读取数据并赋值给ECXecx=SS:[ESP]堆栈指针ESP增加4ESP=ESP+4popr/m16popr/m32(二)堆栈操作1.堆栈:②出栈操作/弹出堆栈ESP00000006000000A500000001000000020000100000000FFC00000FF800000FF400000FF0出栈之前ESP00000006000000A500000001000000020000100000000FFC00000FF800000FF400000FF0出栈之后ESPecx=0000000220临时借用寄存器①把寄存器推入堆栈②使用寄存器③从堆栈中恢复寄存器原值CALL指令执行时,CPU用堆栈保存当前过程的返回地址。调用过程时,可通过堆栈传递参数。(二)堆栈操作1.堆栈:③堆栈的用途21注意事项:保护模式下的立即数总是32位的在实地址模式下,默认的立即数是16位的,除非使用.386(或更高)处理器伪指令32位程序:PUSHFD指令在堆栈上压入32位的EFLAGS寄存器的值。POPFD指令将堆栈顶部的值弹出并送至EFLAGS寄存器。实地址模式程序:PUSHF指令在堆栈上压入16位的FLAGS寄存器的值。POPF指令从堆栈顶部弹出16位的值并送到FLAGS寄存器。22举例:将标志保存在变量中。.datasaveFlagsDWORD?.code…………pushfd;标志入栈popsaveFlags;拷贝到变量里面…………pushsaveFlags;将保存的标志入栈popfd;恢复标志…………23PUSHAD指令在堆栈上按下列顺序压入所有32位通用寄存器:EAX、ECX、EDX、EBX、ESP,EBP、ESI、EDI。POPAD指令以相反的顺序从堆栈中弹出这些通用寄存器。PUSHA和POPA仅用于80286处理器:PUSHA指令:以同样的顺序压入所有的16位寄存器(AX、CX、DX、BX、SP,BP、SI、DI)。POPA指令:以相反的顺序从堆栈中弹出这些通用寄存器。PUSHAD,PUSHA,POPAD和POPA指令24如果在过程中修改了很多寄存器,则可以考虑使用PUSHAD和POPAD指令保存和恢复寄存器的值。MySubPROCpushad;保存通用寄存器的值..moveax,...movedx,...movecx,.....popad;恢复通用寄存器的值retMySubENDP2.PUSH和POP指令④PUSHAD,PUSHA,POPAD和POPA指令25TITLEProgramTemplate(RevStr.asm);Thisprogramreversesastring.INCLUDEIrvine32.inc.dataaNameBYTEAbrahamLincoln,0nameSize=($-aName)-1.codemainPROC;Pushthenameonthestack.movecx,nameSizemovesi,0L1:movzxeax,aName[esi];getcharacterpusheax;pushonstackincesiLoopL12.PUSH和POP指令⑤例子:翻转字符串26;Popthenamefromthestack,inreverse,;andstoreintheaNamearray.movecx,nameSizemovesi,0L2:popeax;getcharactermovaName[esi],al;storeinstringincesiLoopL2;Displaythename.movedx,OFFSETaNamecallWritestringcallCrlfexitmainENDPENDmain2.PUSH和POP指令⑤例子:翻转字符串27把复杂的问题分解成一系列的步骤汇编语言——过程,procedure(三)过程的定义和使用28过程用PROC和ENDP伪指令来声明(三)过程的定义和使用1.PROC伪指令①过程的定义mainPROC..exitmainENDPsamplePROC..retsampleENDP启动过程创建除了启动过程之外的其它过程movah,4Chint21hINVOKEExitProcess,0或保护模式实模式29SumOfPROCaddeax,ebxaddeax,ecxretSumOfENDP(三)过程的定义和使用1.PROC伪指令②例子:三个整数之和30过程完成的任务描述。输入参数的清单及使用方法。过程返回值/出口参数的描述。列出特殊要求,即调用过程之前必须满足的条件。例如上例中三个整数之和的说明;----------
本文标题:11第三章Intel处理器指令系统及汇编语言_1.
链接地址:https://www.777doc.com/doc-3059148 .html