版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
匯編與接口技術
第五章子程序設計子程序定義使用過程定義偽指令PROC定義子程序子程序名 PROC [類型]
…… RET子程序名 ENDP在Win32匯編語言中,PROC后面還可以跟其他參數(shù)子程序一定要在代碼段中定義,在子程序結束時,要用RET指令返回主程序。使用CALL指令來調用子程序,其中子程序名可以通過直接或間接方法給出與子程序類型相對應,CALL指令分為有段內和段間調用主程序和子程序可以在同一個代碼段也可以在不同代碼段。由于32位匯編程序的內存模式為FLAT,一個段長可達4GB,所以本節(jié)主要討論段內調用。如果設計實模式程序,則應注意一個段長不能超過64KB設計子程序時應注意的問題1.寄存器的保存與恢復2.保持堆棧平衡3.子程序說明堆棧的用途16位程序中以字為單位進行,32位程序中以雙字為單位進行(1)保護和恢復調用現(xiàn)場。PUSH EAXPUSH EBX……POP EBXPOP EAX(2)用于變量之間的數(shù)據(jù)傳遞PUSH Var1POP Var2交換兩個變量Var1和Var2的值。PUSH Var1PUSH Var2POP Var1 ;Var1中現(xiàn)在的值是原先Var2的值POP Var2 ;Var2中現(xiàn)在的值是原先Var1的值(3)用做臨時的數(shù)據(jù)區(qū)PUSHCount……POPCount將EAX中的內容轉換為十進制字符串對這個數(shù)連續(xù)除以10,直到所得的商為0結束。每次除法得到的商加上‘0’就可以轉換為ASCII字符。第1次除法所得的余數(shù)是最低位,應該放在最后面,作為字符串的最后一個字符;最后1次除法所得的余數(shù)是最高位,應該作為字符串的第一個字符。szStr
BYTE 10DUP(0)MOV EAX,8192XOR EDX,EDXXOR ECX,ECXMOV EBX,10a10:DIV EBX ;EDX:EAX除以10PUSH EDX ;余數(shù)在EDX中,EDX壓棧INC ECX ;ECX表示壓棧的次數(shù)XOR EDX,EDX;EDX:EAX=下一次除法的被除數(shù)CMP EAX,EDX;被除數(shù)=0?JNZ a10 ;如果被除數(shù)為0,不再循環(huán)MOV EDI,OFFSETszStra20:POP EAX ;從堆棧中取出商ADD AL,'0' ;轉換為ASCII碼MOV [EDI],AL ;保存在szStr中INC EDILOOP a20 ;循環(huán)處理MOV BYTEPTR[EDI],0返回地址作為一個雙字壓棧設計兩個子程序:第1個子程序AddProc1使用ESI和EDI作為加數(shù),做完加法后把和放在EAX中;第2個子程序AddProc2使用X和Y作為加數(shù),做完加法后把和放在Z中。主程序先后調用兩個子程序,最后將結果顯示出來。.386.modelflat,stdcalloptioncasemap:noneincludelib msvcrt.libprintf PROTOC :dword,:vararg.dataszFmt byte '%d+%d=%d',0ah,0 ;輸出結果格式字符串x dword ?y dword ?z dword ?.codeAddProc1 proc ;使用寄存器作為參數(shù) mov eax,esi ;EAX=ESI+EDI add eax,edi retAddProc1 endpAddProc2 proc ;使用變量作為參數(shù) push eax ;C=A+B mov eax,x add eax,y mov z,eax pop eax ;恢復EAX的值 retAddProc2 endpstart: mov esi,10 mov edi,20 ;為子程序準備參數(shù) call AddProc1 ;調用子程序 ;結果在EAX中 mov x,50 mov y,60 ;為子程序準備參數(shù) call AddProc2 ;調用子程序 ;結果在Z中 invoke printf,offsetszFmt, esi,edi,eax ;顯示第1次加法結果 invoke printf,offsetszFmt, x,y,z ;顯示第2次加法結果 retend start參數(shù)傳遞在主程序和子程序中傳遞參數(shù),通常有3種方法:通過寄存器傳遞、通過數(shù)據(jù)區(qū)的變量傳遞、通過堆棧傳遞。在C/C++以及其他高級語言中,函數(shù)的參數(shù)是通過堆棧來傳遞的。C語言中的庫函數(shù),以及WindowsAPI等也都使用堆棧方式來傳遞參數(shù)。例如:MessageBox就屬于WindowsAPI函數(shù),而printf、scanf屬于C的庫函數(shù)。C函數(shù)常見的有5種參數(shù)傳遞方式cdecl方式cdecl方式是C函數(shù)的默認方式,不加說明時,函數(shù)就使用cdecl調用規(guī)則。設計一個通過堆棧傳遞函數(shù)參數(shù)的C程序。函數(shù)subproc()有兩個整型參數(shù),參數(shù)名為a和b。函數(shù)的功能是計算a-b,減法的結果作為函數(shù)的返回值。cdecl方式(1)使用堆棧傳遞參數(shù)。(2)主程序按從右向左的順序將參數(shù)逐個壓棧。最后一個參數(shù)先入棧。每一個參數(shù)壓棧一次,在堆棧中占4字節(jié)。(3)在子程序中,使用[EBP+X]的方式來訪問參數(shù)。X=8代表第1個參數(shù);X=12代表第2個參數(shù),依次類推。(4)子程序用RET指令返回。(5)由主程序執(zhí)行“ADDESP,N”指令調整ESP,達到堆棧平衡。N等于參數(shù)個數(shù)乘以4。每個參數(shù)在堆棧中占4字節(jié)。(6)子程序的返回值放在EAX中。C程序intsubproc(inta,intb){ returna-b;}intr,s;intmain(){ r=subproc(30,20); s=subproc(r,-1);}編譯后的機器指令。subproc函數(shù)的地址為00401000H,main函數(shù)的地址為0040100BH。主程序在調用subproc函數(shù)前,將20、30壓棧。子程序通過[EBP+8]取得堆棧中的參數(shù)a,通過[EBP+0CH]取得堆棧中的參數(shù)b。子程序返回主程序后,主程序執(zhí)行“ADDESP,8”,意味著30、20出棧。00401000 PUSH EBP00401001 MOV EBP,ESP00401003MOV EAX,DWORDPTR[EBP+8]00401006 SUB EAX,DWORDPTR[EBP+0CH]00401009 POP EBP0040100A RET0040100B PUSH EBP0040100C MOV EBP,ESP0040100E PUSH 14H00401010PUSH 1EH00401012 CALL 0040100000401017ADD ESP,80040101AMOV [00405428],EAX0040101FPUSH 0FFFFFFFFH00401021 MOV EAX,[00405428]00401026PUSH EAX00401027CALL 004010000040102CADD ESP,80040102FMOV [0040542C],EAX00401034POP EBP00401035 RETstdcall方式stdcall方式的調用規(guī)則也是使用堆棧傳遞參數(shù),使用從右向左的順序將參數(shù)入棧。與cdecl方式不同的是,堆棧的平衡是由子程序來完成的。子程序使用“RETn”指令,在返回主程序的同時平衡ESP。子程序的返回值放在EAX中。WindowsAPI采用的調用規(guī)則就是stdcall方式int__stdcallsubproc(inta,intb) //兩個下劃線{ returna-b;}intr,s;intmain(){ r=subproc(30,20); s=subproc(r,-1);}fastcall方式這種方式和stdcall類似。區(qū)別是它使用ECX傳遞第1個參數(shù),EDX傳遞第2個參數(shù)。其余的參數(shù)采用從右至左的順序入棧,由子程序在返回時平衡堆棧。例如:int_fastcalladdproc(inta,intb,intc,intd)this方式這種方式和stdcall類似,在C++類的成員函數(shù)中使用。它使用ECX傳遞this指針。naked方式前面4種方式中,編譯器自動為函數(shù)生成進入代碼和退出代碼。進入代碼的形式為:00401000PUSH EBP00401001MOV EBP,ESP退出代碼的形式為:00401009POP EBP0040100ARET 8如果不想讓編譯器生成這些進入代碼和退出代碼,而是要由編程者自行編寫函數(shù)內的所有代碼。這時,就可以使用naked調用規(guī)則。匯編語言子程序的參數(shù)傳遞方式匯編語言中,向子程序傳遞參數(shù)可以仿照C程序的方式來處理子程序參數(shù)傳遞SubProc1采用cdecl方式,而SubProc2采用stdcall方式.386.modelflat,stdcall.data.codeSubProc1proc ;使用堆棧傳遞參數(shù)push ebpmov ebp,espmov eax,dwordptr[ebp+8] ;取出第1個參數(shù)subeax,dwordptr[ebp+12] ;取出第2個參數(shù)popebp ret SubProc1endpSubProc2proc ;使用堆棧傳遞參數(shù)push ebpmov ebp,espmov eax,dwordptr[ebp+8] ;取出第1個參數(shù)sub eax,dwordptr[ebp+12] ;取出第2個參數(shù)pop ebp ret 8 ;平衡主程序的堆棧SubProc2endpstart:push 10 ;第2個參數(shù)入棧push 20 ;第1個參數(shù)入棧call SubProc1 ;調用子程序add esp,8push 100 ;第2個參數(shù)入棧push 200 ;第1個參數(shù)入棧call SubProc2 ;調用子程序retendstart分析在調用“SubProc1”之前,主程序將10、20壓入堆棧;執(zhí)行“callSubProc1”之后,返回地址被壓入堆棧;執(zhí)行“pushebp”、“movebp,esp”之后,EBP被壓入堆棧。此時,[EBP+8]的內容為20,即子程序的第1個參數(shù),[EBP+12]的內容為10,是子程序的第2個參數(shù)。帶參數(shù)子程序的調用MASM提供了一個偽指令INVOKE來簡化子程序的設計和調用。在定義子程序時,可以說明是使用cdecl規(guī)則還是stdcall規(guī)則,并指出各參數(shù)的名稱。在調用子程序時,使用INVOKE偽指令,后面跟子程序名和各個參數(shù)即可,由編譯軟件在編譯時完成將參數(shù)轉換為[EBP+x]等工作。重新前面的程序:定義SubProc1時,后面跟“C”,表示它使用cdecl調用規(guī)則(C語言默認的規(guī)則)。定義SubProc2時,后面跟“stdcall”,表示它使用stdcall調用規(guī)則。調用規(guī)則后面直接跟參數(shù)的名字和類型。子程序中,不需要使用[EBP+8]、[EBP+12]等形式來指定參數(shù),而直接使用a、b等形式參數(shù)即可。MASM自動地將a替換為[EBP+8],將b替換為[EBP+12]。子程序開始的地方也不再需要“PUSHEBP”、“MOVEBP,ESP”指令,結束時也不需要“POPEBP”指令。編譯時,MASM自動在子程序開始的地方插入“PUSHEBP”、“MOVEBP,ESP”指令如果使用了stdcall調用規(guī)則,MASM自動將“RET”指令替換為“RETn”指令。n等于參數(shù)個數(shù)乘以4。.386.modelflat,stdcallincludelibmsvcrt.libprintf
PROTOC:dword,:vararg.dataszMsgOut
byte '%d-%d=%d',0ah,0.codeSubProc1 proc Ca:dword,b:dword ;使用C規(guī)則 mov eax,a ;取出第1個參數(shù) sub eax,b ;取出第2個參數(shù) ret ;返回值=a-bSubProc1 endpSubProc2 proc stdcalla:dword,b:dword ;使用stdcall規(guī)則 mov eax,a ;取出第1個參數(shù) sub eax,b ;取出第2個參數(shù) ret ;返回值=a-bSubProc2 endpstart: invoke SubProc1,20,10 invoke printf,offsetszMsgOut,20,10,eax
invoke SubProc2,200,100 invoke printf,offsetszMsgOut,200,100,eax retend start注意在子程序中不能隨意改變EBP的值,因為子程序要依靠EBP來訪問位于堆棧中的參數(shù)。invoke偽指令后面跟的參數(shù)不能像C語言那樣靈活。在C語言中,參數(shù)本身可以是一個表達式,例如SubProc1(r*2,30)。在匯編語言中,invoke偽指令后面跟的參數(shù)必須直接能夠作為PUSH指令的源操作數(shù),因此,下面這樣的指令是不符合規(guī)則的,編譯時會報錯:invokeSubProc1,r*2,30子程序中的局部變量局部變量只供子程序內部使用,使用局部變量能提高程序的模塊化程度,節(jié)約內存空間。局部變量也被稱為自動變量。在高級語言中,局部變量的實現(xiàn)原理如下。(1)在進入子程序的時候,通過修改堆棧指針ESP來預留出需要的空間。用SUBESP,x指令預留空間,x為該子程序中所有局部變量使用的空間。(2)在返回主程序之前,通過恢復ESP來釋放這些空間,在堆棧中不再為子程序的局部變量保留空間。MASM提供了LOCAL偽指令,可以在子程序中方便地定義局部變量。LOCAL變量名1[重復數(shù)量][:類型],變量名2[重復數(shù)量][:類型]……LOCAL偽指令必須緊接在子程序定義的偽指令PROC之后,可以使用多個LOCAL語句。變量類型可以是BYTE、WORD、DWORD等。還可以定義一個局部的結構變量,此時可以用結構的名稱當作類型。在子程序中還可以定義一個局部數(shù)組LOCALTEMP[3]:DWORDTEMP數(shù)組有3個元素。每個元素占4字節(jié),TEMP數(shù)組在堆棧中占12字節(jié)。在程序中使用TEMP[0]代表第0個元素,TEMP[4]代表第1個元素,TEMP[8]代表第2個元素。如果在子程序中定義了局部變量,而在INVOKE語句中使用這個局部變量的地址,就需要用到ADDR偽操作符,而不能使用OFFSET偽操作符。OFFSET后面只能跟全局變量(即在數(shù)據(jù)區(qū)中定義的變量)和程序中的標號,不能跟局部變量。LOCALTEMP1,TEMP2:DWORDMASM將TEMP1作為[EBP-4],將TEMP2作為[EBP-8]。但子程序中直接使用TEMP1、TEMP2,而不必使用[EBP-4]、[EBP-8]的形式。SWAP的兩個入口參數(shù)a和b是兩個指針,所以a和b的類型用“PTRDWORD”說明。.386.modelflat,stdcallincludelib msvcrt.libprintf PROTOc
:dword,:vararg.datar dword10s dword20szMsgOut byte 'r=%ds=%d',0ah,0.codeswap proc Ca:ptrdword,b:ptrdword ;使用堆棧傳遞參數(shù) local temp1,temp2:dword mov eax,a mov ecx,[eax] mov temp1,ecx ;temp1=*a mov ebx,b mov edx,[ebx] mov temp2,edx ;temp2=*b mov ecx,temp2 mov eax,a mov [eax],ecx ;*a=temp2 mov ebx,b mov edx,temp1 mov [ebx],edx ;*b=temp1 retswap endpstart proc invoke printf,offsetszMsgOut,r,s invoke swap,offsetr,offsets invoke printf,offsetszMsgOut,r,s retstart endpend start子程序嵌套(不舉例)子程序遞歸計算n!(n的階乘)n!=n×(n-1)! (若n>1)n!=1 (若n=0,1)分析:子程序factorial將n作為參數(shù),結果n!放置在EAX中。子程序中首先判斷n是否小于等于1,若是,返回1即可;否則調用它自己求出(n-1)!,調用它自身時,以n-1作為子程序的參數(shù),求出(n-1)!后,再將它乘以n放置在EAX中,作為子程序的返回值。.386.modelflat,stdcallincludelib
msvcrt.libprintfPROTOC:dword,:vararg.dataszOutbyte 'n=%d(n!)=%d',0AH,0.codefactorial proc Cn:dword cmp n,1 jbe exitrecurse mov ebx,n ;EBX=n dec ebx ;EBX=n-1 invoke factorial,ebx ;EAX=(n-1)! imul n ;EAX=EAX*n ret ;=(n-1)!*n=n!exitrecurse: mov eax,1 ;n=1時,n!=1 retfactorial endpstart proc local n,f:dword mov n,5 invoke factorial,n ;EAX=n! mov f,eax invoke printf,offsetszOut,n,f retstart endpend start緩沖區(qū)溢出緩沖區(qū)溢出是由編程錯誤引起的,當程序向緩沖區(qū)內寫入的數(shù)據(jù)超過了緩沖區(qū)的容量,就發(fā)生了緩沖區(qū)溢出,緩沖區(qū)之外的內存單元被程序“非法”修改。攻擊者利用程序中的漏洞,精心設計出一段入侵程序代碼,覆蓋緩沖區(qū)之外的內存單元,這些程序代碼就可以被CPU所執(zhí)行,從而獲取系統(tǒng)的控制權。模塊化程序設計有多個源程序文件,或者需要使用C/C++、匯編等多種語言混合編程,就需要對這些源程序分別編譯,最后連接構成一個可執(zhí)行文件。通過對系統(tǒng)功能的分析,采取“分而治之”的辦法,將一個大的系統(tǒng)分解為小的模塊,每一個模塊都可以采取不同的編程語言。各個模塊的開發(fā)可以由多個開發(fā)人員并行完成,最后,將所有模塊組合成為一個完整的系統(tǒng)。模塊間的通信由于各個模塊需要單獨匯編,于是就會出現(xiàn)當一個模塊通過名字調用另一模塊中的子程序或使用其數(shù)據(jù)時,這些名字對于調用者來講是未定義的,因此在匯編過程中就會出現(xiàn)符號未定義錯誤??梢酝ㄟ^偽指令EXTRN、PUBLIC等來解決。外部引用偽指令格式:EXTRN/EXTERN變量名:類型[,…]功能:說明在本模塊中用到的變量是在另一個模塊中定義的,同時指出變量的類型。說明:這里的名字一般是變量名,變量是在另一模塊中定義的。類型可以是BYTE、WORD、DWORD,與另一模塊對該變量的定義要一致。EXTRN偽指令應該出現(xiàn)在程序引用該名字之前,一般放在程序的開頭。全局符號說明偽指令格式:PUBLIC名字[,…]功能:告訴匯編程序本模塊中定義的名字可以被其他模塊使用。這里的名字可以是變量名,也可以是子程序名。子程序聲明偽指令格式:子程序名PROTO[C|stdcall]:[第一個參數(shù)類型][,:后續(xù)參數(shù)類型]功能:說明子程序的名字和參數(shù)類型,供主程序調用。在模塊化程序設計中,若子程序位于另一模塊,則在主程序模塊中,就需要用PROTO偽指令對子程序的名字、調用方式和參數(shù)類型予以說明。設計由兩個模塊組成的程序,模塊名分別為PROG0509.ASM和PROG0510.ASM。其中主模塊調用子模塊中的SubProc子程序實現(xiàn)減法功能。;PROG0509.asm.386.model flat,stdcalloption casemap:noneincludelib msvcrt.libprintf PROTOC:dword,:varargSubProcPROTOstdcall:dword,:dword ;SubProc位于其他模塊中public result ;允許其他模塊使用result.dataszOutputFmtStr byte '%d-%d=%d',0ah,0 ;輸出結果oprd1 dword 70 ;被減數(shù)oprd2 dword 40 ;減數(shù)result dword ? ;差.codemain proc Cargc,argv invoke SubProc,oprd1,oprd2 ;調用其他模塊中的函數(shù) invoke printf,offsetszOutputFmtStr,\ ;輸出結果 oprd1,\ oprd2,\ result ;result由SubProc設置 retmain endp end;PROG0510.asm.386.modelflat,stdcallpublic SubProc ;允許其他模塊調用SubProcextrn result:dword ;result位于其他模塊中.data.codeSubProc proc stdcalla,b ;減法函數(shù),stdcall調用方式 mov eax,a ;參數(shù)為a,b sub eax,b ;EAX=a-b mov result,eax ;減法的結果保存在result中 ret 8 ;返回a-bSubProc endp end使用ML分別編譯模塊PROG0509.ASM和PROG0510.ASM,分別得到PROG0509.OBJ和PROG0510.OBJ。最后,再使用LINK將兩個.OBJ文件連接生成一個.EXE文件,使用/out選項來指定產(chǎn)生的.EXE文件名。PROG0509.ASMPROG0510.ASMPROG0509.OBJPROG0509.OBJPROG0510x.ASM匯編鏈接ml/c/coffprog0509.asmml/c/coffprog0510.asmlinkprog0509.objprog0510.obj/out:prog0510x.exe/subsystem:consoleC語言模塊的反匯編C基本框架1: #include"stdio.h"2: intmain()3: {4: return0;5: }在C基本框架中,需要對部分寄存器初始化,并為局部變量在棧上開辟40h的空間,初始化為0CCh。反匯編碼-棧初始化過程00401020 55 push ebp00401021 8BEC mov ebp,esp00401023 83EC40 sub esp,40h00401026 53 push ebx00401027 56 push esi00401028 57 push edi00401029 8D7DC0 lea edi,[ebp-40h]0040102C B910000000 mov ecx,10h00401031 B8CCCCCCCC mov eax,0CCCCCCCCh00401036 F3AB repstos dwordptr[edi]00401038 33C0 xor eax,eax反匯編碼-棧初恢復過程0040103A 5F pop edi0040103B 5E pop esi0040103C 5B pop ebx0040103D 8BE5 mov esp,ebp0040103F 5D pop ebp00401040 C3 retC選擇結構1: inti;2: if(i>=0)3: printf("iisnonnegative!");4: else5: printf("iisnegative!");00401049 837DFC00 cmp dwordptr[ebp-4],00040104D 7C0F jl main+3Eh(0040105e)0040104F 68840F4200 push offsetstring"iisnonnegative!"(00420f84)00401054 E887000000 call printf(004010e0)00401059 83C404 add esp,4;輸出printf("iisnonnegative!");0040105C EB0D jmp main+4Bh(0040106b)0040105E 68740F4200 push offsetstring"iisnegative!"(00420f74)00401063 E878000000 call printf(004010e0)00401068 83C404 add esp,4;輸出printf("iisnegative!");C循環(huán)結構-for1: inti;2: for(i=1;i<=10;i++)3: ;00401038 C745FC01000000 mov dwordptr[ebp-4],1;局部變量i保存在棧中,通過[ebp-4]的方式訪問。0040103F EB09 jmp main+2Ah(0040104a)00401041 8B45FC mov eax,dwordptr[ebp-4]00401044 83C001 add eax,100401047 8945FC mov dwordptr[ebp-4],eax0040104A 837DFC0A cmp dwordptr[ebp-4],0Ah0040104E 7F02 jg main+32h(00401052)00401050 EBEF jmp main+21h(00401041)C-while循環(huán)00401038 C745FC01000000 mov dwordptr[ebp-4],1;局部變量i保存在棧中,通過[ebp-4]的方式訪問。0040103F 837DFC0A cmp dwordptr[ebp-4],0Ah;while(i<=10)00401043 7F0B jg main+30h(00401050)00401045 8B45FC mov eax,dwordptr[ebp-4]00401048 83C001 add eax,10040104B 8945FC mov dwordptr[ebp-4],eax0040104E EBEF jmp main+1Fh(0040103f)C變量定義局部變量保存在棧中,通過[ebp-n]的方式訪問。全局變量和靜態(tài)全局變量保存在內存區(qū)域,通過邏輯地址訪問。1: #include"stdio.h"2: inti1; //全局變量3: staticinti2; //靜態(tài)全局變量4: intmain()5: {6: inti3; //局部變量7: i1=0;8: i2=0;9: i3=0;10: return1;11: }00401028 C705B827420000 mov dwordptr[_i1(004227b8)],0;全局變量i100401032 C705D825420000 mov dwordptr[i2(004225d8)],0;靜態(tài)變量i20040103C C745FC00000000 mov dwordptr[ebp-4],0;局部變量i300401043 B801000000 mov eax,1;返回值保存在eax0040104E C3 retC指針-內存地址1: #include"stdio.h"2: intmain()3: {4: int*p,a;5: a=10;6: p=&a;7: }00401028 C745F80A000000 mov dwordptr[ebp-8],0Ah;a=10,a為局部變量,通過[ebp-n]的方式訪問。0040102F 8D45F8 lea eax,[ebp-8]00401032 8945FC mov dwordptr[ebp-4],eax;p=&a,p為局部變量,p中保存著a的地址。C函數(shù)1: #include"stdio.h"2: intsubproc(inta,intb)3: {4: returna*b;5: }6: intmain()7: {8: intr,s;9: r=subproc(10,8);10: s=subproc(r,-1);11: printf("r=%d,s=%d",r,s);12: }子程序subproc的反匯編碼-棧的初始化00401010 55 push ebp00401011 8BEC mov ebp,esp00401013 83EC40 sub esp,40h00401016 53 push ebx00401017 56 push esi00401018 57 push edi00401019 8D7DC0 lea edi,[ebp-40h]0040101C B910000000 mov ecx,10h00401021 B8CCCCCCCC mov eax,0CCCCCCCCh00401026 F3AB rep stos dwordptr[edi]返回值-保存在eax中00401028 8B4508 mov eax,dwordptr[ebp+8]0040102B 0FAF450C imul eax,dwordptr[ebp+0Ch];eax=a*b棧的恢復0040102F 5F pop edi00401030 5E pop esi00401031 5B pop ebx00401032 8BE5 mov
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年油漆裝飾外包加工合同2篇
- 2024年出租車司機就業(yè)協(xié)議3篇
- 2024年度三方倉儲配送及倉儲設施改造合同范本3篇
- 2024年更新版:快消品公司員工合同2篇
- 山西藝術職業(yè)學院《云平臺技術綜合設計》2023-2024學年第一學期期末試卷
- 山西醫(yī)科大學《光電與光化學轉化原理實驗》2023-2024學年第一學期期末試卷
- 2024年度沙子開采與購銷合作合同規(guī)范6篇
- 2024年無產(chǎn)證房產(chǎn)買賣合同書3篇
- 2024年版木屑供應合同3篇
- 2024年環(huán)保工程項目承包合同
- 廣東省肇慶市2023-2024學年高二上學期期末教學質量檢測試題 政治試題 附答案
- 街道社區(qū)城管工作目標考核細則
- 國開電大專科《Dreamweaver網(wǎng)頁設計》2023-2024期末試題及答案(試卷號:2445)
- 體育概論(第二版)課件第三章體育目的
- 2024年《中華人民共和國監(jiān)察法》知識測試題庫及答案
- 2025屆高考語文復習:散文閱讀 課件
- 《現(xiàn)代漢語》第三章-文字
- 2024年高考英語考前押題密卷(新高考Ⅰ卷)(含答案與解析)
- 期末復習知識點-2024-2025學年統(tǒng)編版道德與法治九年級上冊
- 羽毛球智慧樹知到答案2024年山東工藝美術學院
- 2024年巴西消費級鋰電池包市場機會及渠道調研報告
評論
0/150
提交評論