




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第五章指令集體系結構
程序轉換概述
IA-32指令系統
x86-64指令系統指令集體系結構主要教學目標了解高級語言與匯編語言、匯編語言與機器語言之間的關系掌握有關指令格式、操作數類型、尋址方式、操作類型等內容了解IA-32指令系統中的常用指令類型了解x86-64架構的基本特點和基本指令了解x86-64指令系統與IA-32指令系統的差別主要教學內容介紹C語言程序與IA-32機器級指令之間的對應關系。主要包括:程序轉換概述、指令集體系結構基礎、IA-32指令系統、x86-64指令系統等。本章所用的機器級表示主要以匯編語言形式表示為主。指令集體系結構分以下三個部分介紹第一講:程序轉換概述機器指令和匯編指令機器級程序員感覺到的屬性和功能特性高級語言程序轉換為機器代碼的過程第二講:IA-32指令系統IA-32指令系統概述IA-32常用指令類型X87浮點處理指令MMX/SSE指令集第三講:x86-64指令系統x86-64的發展簡史x86-64的基本特點x86-64的基本指令“指令”的概念有微指令、機器指令、匯編指令、偽(宏)指令等指令相關概念微指令是微程序級命令,屬于硬件范疇機器指令介于二者之間,處于硬件和軟件的交界面匯編指令是機器指令的匯編表示形式,即符號表示機器指令和匯編指令一一對應,它們都與具體機器結構有關,都屬于機器級指令偽指令是由若干匯編指令組成的序列,屬于軟件范疇SKIP回顧:Hardware/SoftwareInterface…,EXTop=1,ALUSelA=1,ALUSelB=11,ALUop=add,IorD=1,Read,MemtoReg=1,RegWr=1,......temp=v[k];v[k]=v[k+1];v[k+1]=temp;lw$15,0($2)lw$16,4($2)sw$16,0($2)sw$15,4($2)10001100010011110000000000000000100011000101000000000000000001001010110001010000000000000000000010101100010011110000000000000100軟件硬件匯編指令機器指令…11111001011…微指令swap0($2),4($2)偽指令BACK機器級指令機器指令和匯編指令一一對應,都是機器級指令機器指令是一個0/1序列,由若干字段組成如8086/8088指令:匯編指令是機器指令的符號表示(可能有不同的格式)mov、movb、bx、%bx等都是助記符指令的功能為:M[R[bx]+R[di]-6]←R[cl]
操作碼尋址方式寄存器編號立即數(位移量)mov[bx+di-6],clmovb%cl,-6(%bx,%di)或Intel格式AT&T格式補碼11111010的真值為多少?寄存器傳送語言RTL(RegisterTransferLanguage)
R:寄存器內容M:存儲單元內容
本課程采用AT&T格式IA-32機器指令格式可以同時出現,無先后順序關系。指令前綴:加鎖(LOCK)和重復執行(REP/REPE/REPZ/REPNE/REPNZ)
兩種,LOCK編碼為F0H,REPNE、REP編碼分別為F2H和F3H段前綴:指定指令所使用的非默認段寄存器,包括2EH(CS)、36H(SS)、3EH(DS)、26H(ES)、64H(FS)、65H(GS)操作數長度和地址長度前綴:分別為66H和67H操作碼:opcode;w:與機器模式(16/32位)一起確定寄存器位數(AL/AX/EAX);d:操作方向,確定Reg是源操作數還是目…尋址方式:mod、r/m、reg/op三個字段與w字段和機器模式一起確定操作數所在的寄存器編號或有效地址計算方式:Mod和R/M共5位,表示另一個操作數的尋址方式,可組合成32種情況,當Mod=11時,為寄存器尋址方式,3位R/M表示寄存器編號,其他24種情況都是存儲器尋址方式。是否在ModR/M字節后跟一個SIB字節,由Mod和R/M組合確定,例如,當Mod=00且R/M=100時,一定跟SIB字節,尋址方式由SIB確定。SIB中基址B和變址I都可以是8個GRS中任一個;SS給出比例因子位移量和立即數的長度可以是:1B(8位)、2B(16位)、4B(32位)IA-32機器指令格式回顧:計算機中數據的存儲計算機中的數據存放在哪里?寄存器文件通用寄存器組GPRs存儲器指令中需給出的信息:操作性質(操作碼)源操作數1或/和源操作數2
(立即數、寄存器編號、存儲地址)目的操作數地址(寄存器編號、存儲地址)存儲地址的描述與操作數的數據結構有關!相當于宿舍書架相當于圖書館書架I/OCPUCompilerOperatingSystemApplicationDigitalDesignCircuitDesignInstructionSetArchitectureMMAssembler回顧:指令集體系結構ISAISA(InstructionSetArchitecture)位于軟件和硬件之間硬件的功能通過ISA提供出來軟件通過ISA規定的”指令”使用硬件ISA規定了:可執行的指令的集合,包括指令格式、操作種類以及每種操作對應的操作數的相應規定;指令可以接受的操作數的類型;操作數所能存放的寄存器組的結構,包括每個寄存器的名稱、編號、長度和用途;操作數所能存放的存儲空間的大小和編址方式;操作數在存儲空間存放時按照大端還是小端方式存放;指令獲取操作數的方式,即尋址方式;指令執行過程的控制方式,包括程序計數器、條件碼定義等。高級語言程序轉換為機器代碼的過程
預處理:在高級語言源程序中插入所有用#include命令指定的文件和用#define聲明指定的宏。編譯:將預處理后的源程序文件編譯生成相應的匯編語言程序。匯編:由匯編程序將匯編語言源程序文件轉換為可重定位的機器語言目標代碼文件。鏈接:由鏈接器將多個可重定位的機器語言目標文件以及庫例程(如printf()庫函數)鏈接起來,生成最終的可執行目標文件。用GCC編譯器套件進行轉換的過程GCC使用舉例add:pushl %ebpmovl %esp,%ebpsubl $16,%espmovl 12(%ebp),%eaxmovl 8(%ebp),%edxleal (%edx,%eax),%eaxmovl %eax,-4(%ebp)movl -4(%ebp),%eaxleaveretgcc-Etest.c-otest.igcc-Stest.i-otest.s
gcc–Stest.c–otest.s
1.file"test.c"2.text3.globladd4.typeadd,@function5add:6.LFB0:7.cfi_startproc8pushl%ebp9.cfi_def_cfa_offset810.cfi_offset5,-811movl%esp,%ebp12.cfi_def_cfa_register513subl$16,%esp14movl8(%ebp),%edx15movl12(%ebp),%eax16leal(%edx,%eax,1),%eax17movl%eax,-4(%ebp)18movl-4(%ebp),%eax19leave20.cfi_restore521.cfi_def_cfa4,422ret23.cfi_endproc24.LFE0:25.sizeadd,.-add26.ident"GCC:(Debian10.2.1-6)10.2.120210110"27.section.note.GNU-stack,"",@progbitstest.s中以“.”開頭的行屬于匯編指示符
匯編指示符1.file"test.c"2.text3.globladd4.typeadd,@function5add:6.LFB0:7.cfi_startproc8pushl%ebp9.cfi_def_cfa_offset810.cfi_offset5,-811movl%esp,%ebp12.cfi_def_cfa_register513subl$16,%esp14movl8(%ebp),%edx15movl12(%ebp),%eax16leal(%edx,%eax,1),%eax17movl%eax,-4(%ebp)18movl-4(%ebp),%eax19leave20.cfi_restore521.cfi_def_cfa4,422ret23.cfi_endproc24.LFE0:25.sizeadd,.-add26.ident"GCC:(Debian10.2.1-6)10.2.120210110"27.section.note.GNU-stack,"",@progbits.file:給出對應的源程序文件名。.text:指示代碼節(.text)從此處開始。.globladd:聲明add是一個全局符號。.typeadd,@function:聲明add是一個函數。.data:指示已初始化數據節.data從此處開始。.bss:指示未初始化數據節.bss從此處開始。.section.rodata:指示只讀數據節從此處開始。.align2:指示代碼此處開始按4字節對齊。.balign4:指示數據此處開始按4字節對齊。.string“Hello,%s!\n”:定義字符串。GCC使用舉例兩個源程序文件test1.c和test2.c,最終生成可執行文件為testgcc-O1test1.ctest2.c-otest選項-O1表示一級優化,-O2為二級優化,選項-o指出輸出文件名add:pushl %ebpmovl %esp,%ebpsubl $16,%espmovl 12(%ebp),%eaxmovl 8(%ebp),%edxleal (%edx,%eax),%eaxmovl %eax,-4(%ebp)movl -4(%ebp),%eaxleaveret00000000<add>:0:55 push%ebp1:89e5 mov%esp,%ebp3:83ec10sub$0x10,%esp6:8b450cmov0xc(%ebp),%eax9:8b5508mov0x8(%ebp),%edxc:8d0402lea(%edx,%eax,1),%eaxf:8945fcmov%eax,-0x4(%ebp)12:8b45fcmov-0x4(%ebp),%eax15:c9leave16:c3retgcc-Etest.c-otest.igcc-Stest.i-otest.s
gcc–Stest.c–otest.s
test.s位移量機器指令匯編指令編譯得到的與反匯編得到的匯編指令形式稍有差異“gcc–ctest.s–otest.o”將test.s匯編為test.o“objdump-dtest.o”將test.o反匯編為
兩種目標文件“objdump-dtest”結果00000000<add>:0:55 push%ebp1:89e5 mov%esp,%ebp3:83ec10sub$0x10,%esp6:8b450cmov0xc(%ebp),%eax9:8b5508mov0x8(%ebp),%edxc:8d0402lea(%edx,%eax,1),%eaxf:8945fcmov%eax,-0x4(%ebp)12:8b45fcmov-0x4(%ebp),%eax15:c9leave16:c3rettest.o中的代碼從地址0開始,test中的代碼從80483d4開始!080483d4<add>:80483d4:55push...80483d5:89e5…80483d7:83ec10…80483da:8b450c…80483dd:8b5508…80483e0:8d0402…80483e3:8945fc…80483e6:8b45fc…80483e9:c9…80483ea:c3
ret
“objdump-dtest.o”結果test.o:可重定位目標文件test:可執行目標文件可執行文件的存儲器映像0ESP(棧頂)brk0xC000000000x08048000內核虛存區共享庫區域堆(heap)(由malloc動態生成)用戶棧(Userstack)動態生成未使用0讀寫數據段(.data,.bss)只讀代碼段(.init,.text,.rodata)從可執行文件裝入程序(段)頭表描述如何映射ELF頭程序(段)頭表.text節.data節.bss節.symtab節.debug節.rodata節.line節.init節.strtab節1GB
從高地址向低地址增長!指令集體系結構分以下三個部分介紹第一講:程序轉換概述機器指令和匯編指令機器級程序員感覺到的屬性和功能特性高級語言程序轉換為機器代碼的過程第二講:IA-32指令系統IA-32指令系統概述IA-32常用指令類型X87浮點處理指令MMX/SSE指令集第三講:x86-64指令系統x86-64的發展簡史x86-64的基本特點x86-64的基本指令IA-32/x64指令系統概述x86是Intel開發的一類處理器體系結構的泛稱包括Intel8086、80286、i386和i486等,因此其架構被稱為“x86”由于數字并不能作為注冊商標,因此,后來使用了可注冊的名稱,如Pentium、PentiumPro、Core2、Corei7等現在Intel把32位x86架構的名稱x86-32改稱為IA-32由AMD首先提出了一個兼容IA-32指令集的64位版本擴充了指令及寄存器長度和個數等,更新了參數傳送方式AMD稱其為AMD64,Intel稱其為Intl64(不同于IA-64)命名為“x86-64”,有時也簡稱為x64回顧:計算機系統核心層之間的關聯前端遵循語言規范高級語言程序詞法、語法及語義分析中間代碼生成中間代碼目標代碼生成及優化目標代碼后端遵循ISA規范和ABI規范后端根據ISA規范和應用程序二進制接口(ApplicationBinaryInterface,ABI)規范進行設計實現。ABI是為運行在特定ISA及特定操作系統之上的應用程序規定的一種機器級目標代碼層接口描述了應用程序和操作系統之間、應用程序和所調用的庫之間、不同組成部分(如過程或函數)之間在較低層次上的機器級代碼接口。運行平臺:操作系統+ISA架構本課程所用平臺為IA-32/x86-64+Linux+GCC+C語言,Linux操作系統下一般使用systemVABI同一個C語言源程序,使用遵循不同ABI規范的編譯器進行編譯,其執行結果可能不一樣。程序員將程序移植到另一個系統時,一定要仔細閱讀目標系統的ABI規范。I386SystemVABI規定的數據類型IA-32的定點寄存器組織8個通用寄存器兩個專用寄存器6個段寄存器IA-32的標志寄存器6個條件標志OF、SF、ZF、CF各是什么標志(條件碼)?AF:輔助進位標志(BCD碼運算時才有意義)PF:奇偶標志3個控制標志DF(DirectionFlag):方向標志(自動變址方向是增還是減)IF(InterruptFlag):中斷允許標志(僅對外部可屏蔽中斷有用)TF(TrapFlag):陷阱標志(是否是單步跟蹤狀態)……808680286/386X87浮點指令、MMX和SSE指令IA-32的浮點處理架構有兩種:浮點協處理器x87架構(x87FPU)8個80位寄存器ST(0)~ST(7)(采用棧結構),棧頂為ST(0)由MMX發展而來的SSE架構MMX指令使用8個64位寄存器MM0~MM7,借用8個80位寄存器ST(0)~ST(7)中64位尾數所占的位,可同時處理8個字節,或4個字,或2個雙字,或一個64位的數據MMX指令并沒帶來3D游戲性能的顯著提升,故相繼推出SSE指令集,它們都采用SIMD(單指令多數據,也稱數據級并行)技術SSE指令集將80位浮點寄存器擴充到128位多媒體擴展通用寄存器XMM0~XMM7,可同時處理16個字節,或8個字,或4個雙字(32位整數或單精度浮點數),或兩個四字的數據,而且從SSE2開始,還支持128位整數運算或同時并行處理兩個64位雙精度浮點數IA-32中通用寄存器中的編號反映了體系結構發展的軌跡,字長不斷擴充,指令保持兼容ST(0)~ST(7)是80位,MM0~MM7使用其低64位基本尋址方式的算法和優缺點方式
算法 主要優點 主要缺點立即數
操作數=A
指令執行速度快操作數幅值有限直接
EA=A有效地址計算簡單地址范圍有限間接
EA=(A)有效地址范圍大多次存儲器訪問寄存器(直接)
操作數=(R)
指令執行快,指令短地址范圍有限寄存器間接
EA=(R)地址范圍大
額外存儲器訪問偏移 EA=A+(R)靈活復雜棧
EA=棧頂指令短應用有限偏移方式:將直接方式和寄存器間接方式結合起來。有:相對/基址/變址三種(見后面幾頁!)
假設:A=地址字段值,R=寄存器編號,
EA=有效地址,(X)=X中的內容問題:以上各種尋址方式下,操作數在寄存器中還是在存儲器中?需要計算有效地址EA的操作數都是在存儲器中OPRA…偏移尋址方式R存儲器操作數寄存器堆A+AOP偏移尋址:EA=A+(R)R可以明顯給出,也可以隱含給出
R可以為PC、基址寄存器B、變址寄存器I
相對尋址:EA=A+(PC)相對于當前指令處位移量為A的單元
基址尋址:EA=A+(B)相對于基址(B)處位移量為A的單元
變址尋址:EA=A+(I)相對于首址A處位移量為(I)的單元......指令中給出的地址碼A稱為形式地址偏移尋址方式相對尋址指令地址碼給出一個偏移量(帶符號數),基準地址隱含由PC給出。即:EA=(PC)+A
(ex.MIPS’sinstruction:Beq)可用來實現程序(公共子程序)的浮動或指定轉移目標地址注意:當前PC的值可以是正在執行指令的地址或下條指令的地址基址尋址指令地址碼給出一個偏移量,基準地址明顯或隱含由基址寄存器B給出。即:EA=(B)+A
(ex.MIPS’sinstructions:lw/sw)可用來實現結構或聯合體分量的訪問或過程調用中參數的訪問變址尋址指令地址碼給出一個基準地址,而偏移量(無符號數)明顯或隱含由變址寄存器I給出。即:EA=(I)+A可為循環重復操作提供一種高效機制,如實現對線性表的方便操作變址尋址實現線性表元素的存取自動變址指令中的地址碼A給定數組首址,變址器I每次自動加/減數組元素的長度x。
EA=A+(I)I=(I)±x
例如,X86中的串操作指令對于“for(i=0;i<N;i++)….”,即地址從低→高變化:加對于“for(i=N-1;i>=0;i--)….”,即地址從高→低變化:減可提供對線性表的方便訪問假設按字節編址,則:每個元素為一個字節時,I=(I)±1每個元素為4個字節時,I=(I)±4A=100變址器I0A[0]A[1]A[2]A[3]存儲器假定一維數組A從100號單元開始一般RISC機器不提供自動變址尋址,并將變址和基址尋址統一成一種偏移尋址方式IA-32的尋址方式尋址方式根據指令給定信息得到操作數或操作數地址操作數所在的位置指令中:立即尋址寄存器中:寄存器尋址存儲單元中(屬于存儲器操作數,按字節編址):其他尋址方式存儲器操作數的尋址方式與微處理器的工作模式有關兩種工作模式:實地址模式和保護模式實地址模式(基本用不到)為與8086/8088兼容而設,加電或復位時尋址空間為1MB,20位地址:(CS)<<4+(IP)保護模式(需要掌握)加電后進入,采用虛擬存儲管理,多任務情況下隔離、保護80286以上高檔微處理器最常用的工作模式尋址空間為232B,32位地址分段(段基址+段內偏移量)保護模式下的尋址方式SR段寄存器(間接)確定操作數所在段的段基址有效地址給出操作數在所在段的偏移地址尋址過程涉及到“分段虛擬管理方式”,將在第6章討論存儲器操作數跳轉目標指令地址存儲器操作數的尋址方式intx;floata[100];shortb[4][4];charc;doubled[10];a[i]的地址如何計算?104+i×4i=99時,104+99×4=500b[i][j]的地址如何計算?504+i×8+j×2i=3、j=2時,504+24+4=532d[i]的地址如何計算?544+i×8i=9時,544+9×8=616b31 b0xa[0]a[99]b[0][1]100104b[0][0]b[3][3]b[3][2]c500504532536544d[0]d[9]616存儲器操作數的尋址方式各變量應采用什么尋址方式?x、c:位移/基址a[i]:104+i×4,比例變址+位移d[i]:544+i×8,比例變址+位移b[i][j]:504+i×8+j×2,基址+比例變址+位移intx;floata[100];shortb[4][4];charc;doubled[10];
b31 b0xa[0]a[99]b[0][1]100104b[0][0]b[3][3]b[3][2]c500504532536544d[0]d[9]616將b[i][j]取到AX中的指令可以是:“movw504(%ebp,%esi,2),%ax”其中,
i×8在EBP中,j在ESI中,
2為比例因子IA-32常用指令類型(1)傳送指令通用數據傳送指令MOV:一般傳送,包括movb、movw和movl等MOVS:符號擴展傳送,如movsbw、movswl等MOVZ:零擴展傳送,如movzwl、movzbl等XCHG:數據交換PUSH/POP:入棧/出棧,如pushl,pushw,popl,popw等地址傳送指令LEA:加載有效地址,如leal(%edx,%eax),%eax”的功能為R[eax]←R[edx]+R[eax],執行前,若R[edx]=i,R[eax]=j,則指令執行后,R[eax]=i+j輸入輸出指令IN和OUT:I/O端口與寄存器之間的交換標志傳送指令PUSHF、POPF:將EFLAG壓棧,或將棧頂內容送EFLAG
“入棧”和“出棧”操作棧(Stack)是一種采用“先進后出”方式進行訪問的一塊存儲區,用于嵌套過程調用。從高地址向低地址增長“棧”不等于“堆棧”(由“堆”和“棧”組成)棧底棧底R[sp]←R[sp]-2、M[R[sp]]←R[ax]R[ax]←M[R[sp]]、[sp]←R[sp]+2為什么AL在棧頂?小端方式!傳送指令舉例將以下Intel格式指令轉換為AT&T格式指令,并說明功能。push ebp mov ebp,espmov edx,DWORDPTR[ebp+8]mov bl,255mov ax,WORDPTR[ebp+edx*4+8]mov WORDPTR[ebp+20],dxlea eax,[ecx+edx*4+8]pushl %ebp //R[esp]←R[esp]-4,M[R[esp]]←R[ebp],雙字movl %esp,%ebp //R[ebp]←R[esp],雙字movl 8(%ebp),%edx//R[edx]←M[R[ebp]+8],雙字movb $255,%bl //R[bl]←255,字節movw 8(%ebp,%edx,4),%ax//R[ax]←M[R[ebp]+R[edx]×4+8],字movw %dx,20(%ebp) //M[R[ebp]+20]←R[dx],字leal 8(%ecx,%edx,4),%eax//R[eax]←R[ecx]+R[edx]×4+8,雙字IA-32常用指令類型(2)定點算術運算指令加/減運算(影響標志、不區分無/帶符號)ADD:加,包括addb、addw、addl等SUB:減,包括subb、subw、subl等增1/減1運算(影響除CF以外的標志、不區分無/帶符號)INC:加,包括incb、incw、incl等DEC:減,包括decb、decw、decl等取負運算(影響標志、若對0取負,則結果為0且CF=0,否則CF=1)NEG:取負,包括negb、negw、negl等比較運算(做減法得到標志、不區分無/帶符號)CMP:比較,包括cmpb、cmpw、cmpl等乘/除運算(區分無/帶符號)MUL/IMUL:無符號乘/帶符號乘(影響標志OF和CF)DIV/IDIV:無符號除/帶符號除整數乘除指令乘法指令:可給出一個、兩個或三個操作數mul、imul:若給出一個操作數SRC,則另一個源操作數隱含在AL/AX/EAX中,將SRC和累加器內容相乘,結果存放在AX(16位)或DX-AX(32位)或EDX-EAX(64位)中。DX-AX表示32位乘積的高、低16位分別在DX和AX中。n位×n位=2n位imul:若指令中給出兩個操作數DST和SRC,則將DST和SRC相乘,結果在DST中。n位×n位=n位imul:若指令中給出三個操作數REG、SRC和IMM,則將SRC和立即數IMM相乘,結果在REG中。n位×n位=n位除法指令:只明顯指出除數若為8位,則16位被除數在AX寄存器中,商送回AL,余數在AH若為16位,則32位被除數在DX-AX寄存器中,商送回AX,余數在DX若為32位,則被除數在EDX-EAX寄存器中,商送EAX,余數在EDX
以上內容不要死記硬背,遇到具體指令時能查閱到并理解即可。定點算術運算指令匯總定點加法指令舉例假設R[ax]=FFFAH,R[bx]=FFF0H,則執行以下指令后
“addw%bx,%ax”
AX、BX中的內容各是什么?標志CF、OF、ZF、SF各是什么?要求分別將操作數作為無符號數和帶符號整數解釋并驗證指令執行結果。解:功能:R[ax]←R[ax]+R[bx],指令執行后的結果如下
R[ax]=FFFAH+FFF0H=FFEAH,BX中內容不變
CF=1,OF=0,ZF=0,SF=1
若是無符號整數運算,則CF=1說明結果溢出驗證:FFFA的真值為65535-5=65530,FFF0的真值為65520FFEA的真值為65535-21=65514≠65530+65520,即溢出
若是帶符號整數運算,則OF=0說明結果沒有溢出驗證:FFFA的真值為-6,FFF0的真值為-16FFEA的真值為-22=-6+(-16),結果正確,無溢出定點乘法指令舉例假設R[eax]=000000B4H,R[ebx]=00000011H,M[000000F8H]=000000A0H,請問:(1)執行指令“mulb%bl”后,哪些寄存器的內容會發生變化?是否與執行“imulb%bl”指令所發生的變化一樣?為什么?請用該例給出的數據驗證你的結論。解:“mulb%bl”功能為R[ax]←R[al]×R[bl],執行結果如下R[ax]=B4H×11H(無符號整數180和17相乘)
R[ax]=0BF4H,真值為3060=180×17
“imulb%bl”功能為R[ax]←R[al]×R[bl]R[ax]=B4H×11H(帶符號整數-76和17相乘)
R[ax]=0BF4H?則真值為3060≠-76×17 R[al]=F4H,R[ah]=?AH中的值不一樣!R[ax]=FAF4H,真值為-1292=-76×171011010000010001x10110100101101000000101111110100AL=?AH=?對于帶符號乘,若積只取低n位,則和無符號相同;若取2n位,則采用“布斯”乘法無符號乘:定點乘法指令舉例布斯乘法:10110100001-1001-1000100010x0000000001001100111111110110100000001001100111101101001111101011110100AL=?AH=?R[ax]=FAF4H,真值為-1292=-76×17R[ax]=B4H×11H“imulb%bl”定點乘法指令舉例假設R[eax]=000000B4H,R[ebx]=00000011H,M[000000F8H]=000000A0H,請問:(2)執行指令“imull$-16,(%eax,%ebx,4),%eax”后哪些寄存器和存儲單元發生了變化?乘積的機器數和真值各是多少?解:“imull-16,(%eax,%ebx,4),%eax”
功能為R[eax]←(-16)×M[R[eax]+R[ebx]×4],執行結果如下R[eax]+R[ebx]×4=000000B4H+00000011H<<2=000000F8H
R[eax]=(-16)×M[000000F8H]=(-16)×000000A0H(帶符號整數乘)=FFFFFF60H<<4 =FFFFF600HEAX中的真值為-2560SKIP整數乘除指令乘法指令:可給出一個、兩個或三個操作數若給出一個操作數SRC,則另一個源操作數隱含在AL/AX/EAX中,將SRC和累加器內容相乘,結果存放在AX(16位)或DX-AX(32位)或EDX-EAX(64位)中。DX-AX表示32位乘積的高、低16位分別在DX和AX中。若指令中給出兩個操作數DST和SRC,則將DST和SRC相乘,結果在DST中。若指令中給出三個操作數REG、SRC和IMM,則將SRC和立即數IMM相乘,結果在REG中。除法指令:只明顯指出除數,用EDX-EAX中內容除以指定的除數若為8位,則16位被除數在AX寄存器中,商送回AL,余數在AH若為16位,則32位被除數在DX-AX寄存器中,商送回AX,余數在DX若為32位,則被除數在EDX-EAX寄存器中,商送EAX,余數在EDX
以上內容不要死記硬背,遇到具體指令時能查閱到并理解即可。BACKBACKIA-32常用指令類型(3)按位運算指令邏輯運算(僅NOT不影響標志,其他指令OF=CF=0,而ZF和SF根據結果設置:若全0,則ZF=1;若最高位為1,則SF=1)NOT:非,包括notb、notw、notl等AND:與,包括andb、andw、andl等OR:或,包括orb、orw、orl等XOR:異或,包括xorb、xorw、xorl等TEST:做“與”操作測試,僅影響標志移位運算(左/右移時,最高/最低位送CF)SHL/SHR:邏輯左/右移,包括shlb、shrw、shrl等SAL/SAR:算術左/右移,左移判溢出,右移高位補符(移位前、后符號位發生變化,則OF=1)ROL/ROR:循環左/右移,包括rolb、rorw、roll等RCL/RCR:帶循環左/右移,將CF作為操作數一部分循環移位以上內容不要死記硬背,遇到具體指令時能查閱到并理解即可。按位運算指令舉例假設short型變量x被編譯器分配在寄存器AX中,R[ax]=FF80H,則以下匯編代碼段執行后變量x的機器數和真值分別是多少?
movw%ax,%dxsalw$2,%axaddl%dx,%axsarw$1,%ax解:$2和$1分別表示立即數2和1。
x是short型變量,故都是算術移位指令,并進行帶符號整數加。假設上述代碼段執行前R[ax]=x,則執行((x<<2)+x)>>1后,R[ax]=5x/2。算術左移時,AX中的內容在移位前、后符號未發生變化,故OF=0,沒有溢出。最終AX的內容為FEC0H,解釋為short型整數時,其值為-320。驗證:x=-128,5x/2=-320。經驗證,結果正確。1111111110000000<<21111111110000000+11111110000000001111110110000000>>1=1111111011000000逆向工程:從匯編指令退出高級語言程序代碼移位指令舉例算術邏輯IA-32常用指令類型(4)控制轉移指令
指令執行可按順序或跳轉到轉移目標指令處執行無條件轉移指令JMPDST:無條件轉移到目標指令DST處執行條件轉移JccDST:cc為條件碼,根據標志(條件碼)判斷是否滿足條件,若滿足,則轉移到目標指令DST處執行,否則按順序執行條件設置SETccDST:將條件碼cc保存到DST(通常是一個8位寄存器)調用和返回指令
(用于過程調用)CALLDST:返回地址RA入棧,轉DST處執行RET:從棧中取出返回地址RA,轉到RA處執行中斷指令
(詳見第7、8章)以上內容不要死記硬背,遇到具體指令時能查閱到并理解即可。條件轉移指令分三類:(1)根據單個標志的值轉移(2)按無符號整數比較轉移(3)按帶符號整數比較轉移標志信息是干什么的?Ex1:-7-6=-7+(-6)=+36-(-7)=6+7=-3
9-6=3
6-9=1311+000111100010做減法以比較大小,規則:Unsigned:CF=0時,大于Signed:OF=SF時,大于OF=1、ZF=0SF=0、借位CF=0+1101101001111010OF=1、ZF=0SF=1、借位CF=1例子:C表達式類型轉換順序unsignedlonglong↑longlong↑unsigned↑
int↑(unsigned)char,short條件設置指令SETccDST:將條件碼cc保存到DST(通常是一個8位寄存器)猜測:各用哪種條件設置指令?charc=-1;d=(a>c)?1:0unsignedshortb=1;unsignedinta=1;d=(b>c)?1:0無符號帶符號例子:程序的機器級表示與執行intsum(inta[],unsignedlen){inti,sum=0;for(i=0;i<=len–1;i++) sum+=a[i];returnsum;}當參數len為0時,返回值應該是0,但是在機器上執行時,卻發生了存儲器訪問異常。
Why?sum:….L3:…movl-4(%ebp),%eaxmovl12(%ebp),%edxsubl$1,%edxcmpl%edx,%eaxjbe .L3…i在%eax中,len在%edx中%eax:0000……0000%edx:0000……0000subl指令的執行結果是什么?cmpl指令的執行結果是什么?i和len分別存放在哪個寄存器中?%eax?%edx?subl$1,%edx指令的執行結果“subl$1,%edx”執行時:A=00000000H,B為00000001H,Sub=1,因此Result是32個1。Result加法器nnnAZFCiConBn01多路選擇器SubBOF加/減運算部件CF=CoSubSF當Sub為1時,做減法當Sub為0時,做加法已知EDX中為len=00000000Hcpml%edx,%eax指令的執行結果“cmpl%edx,%eax”執行時:A=00000000H,B為FFFFFFFFH,Sub=1,因此Result是0…01,CF=1,ZF=0,OF=0,SF=0
Result加法器nnnAZFCiConBn01多路選擇器SubBOF加/減運算部件CF=CoSubSF當Sub為1時,做減法當Sub為0時,做加法已知EDX中為len-1=FFFFFFFFH
EAX中為i=00000000Hjbe.L3指令的執行結果指令轉移條件說明JA/JNBElabelCF=0ANDZF=0無符號數A>BJAE/JNBlabelCF=0ORZF=1無符號數A≥BJB/JNAElabelCF=1ANDZF=0無符號數A<BJBE/JNAlabelCF=1ORZF=1無符號數A≤BJG/JNLElabelSF=OFANDZF=0有符號數A>BJGE/JNLlabelSF=OFORZF=1有符號數A≥BJL/JNGElabelSF≠OFANDZF=0有符號數A<BJLE/JNGlabelSF≠OFORZF=1有符號數A≤B“cmpl%edx,%eax”執行結果是
CF=1,ZF=0,OF=0,SF=0,說明滿足條件,應轉移到.L3執行!顯然,對于每個i都滿足條件,因為任何無符號數都比32個1小,因此循環體被不斷執行,最終導致數組訪問越界而發生存儲器訪問異常。例子:程序的機器級表示與執行正確的做法是將參數len聲明為int型。
Why?例:
intsum(inta[],intlen){inti,sum=0;for(i=0;i<=len–1;i++) sum+=a[i];returnsum;}sum:….L3:…movl-4(%ebp),%eaxmovl12(%ebp),%edxsubl$1,%edxcmpl%edx,%eaxjle .L3…i在%eax中,len在%edx中%eax:0000……0000%edx:0000……0000subl指令的執行結果是什么?cmpl指令的執行結果是什么?i和len分別存放在哪個寄存器中?%eax?%edx?jle.L3指令的執行結果指令轉移條件說明JA/JNBElabelCF=0ANDZF=0無符號數A>BJAE/JNBlabelCF=0ORZF=1無符號數A≥BJB/JNAElabelCF=1ANDZF=0無符號數A<BJBE/JNAlabelCF=1ORZF=1無符號數A≤BJG/JNLElabelSF=OFANDZF=0有符號數A>BJGE/JNLlabelSF=OFORZF=1有符號數A≥BJL/JNGElabelSF≠OFANDZF=0有符號數A<BJLE/JNGlabelSF≠OFORZF=1有符號數A≤B“cmpl%edx,%eax”執行結果是CF=1,ZF=0,OF=0,SF=0,
說明不滿足條件,應跳出循環執行,執行結果正常。浮點操作與SIMD指令浮點操作與SIMD指令IA-32的浮點處理架構有兩種
(1)
x86配套的浮點協處理器x87FPU架構,80位浮點寄存器棧
(2)由MMX發展而來的SSE指令集架構,采用的是單指令多數據(SingleInstructionMultiData,SIMD)技術
對于IA-32架構,gcc默認生成x87FPU指令集代碼,如果想要生成SEE指令集代碼,則需要設置適當的編譯選項浮點數采用80位雙精度擴展格式1位符號位s、15位階碼e(偏置常數為16383)、1位顯式首位有效位(explicitleadingsignificantbit)j和63位尾數f。它與IEEE754單精度和雙精度浮點格式的一個重要的區別是,它沒有隱藏位,有效位數共64位。X87FPU指令數據傳送類
從內存裝入棧頂ST(0)帶P結尾指令表示操作數會出棧,也即ST(1)將變成ST(0)
(1)裝入
FLD:將數據裝入浮點寄存器棧頂
FILD:將數據從int型轉換為浮點格式后,裝入浮點寄存器棧頂(2)存儲
FSTx:x為s/l時,將棧頂ST(0)轉換為單/雙精度格式,然后存入存儲單元
FSTPx:彈出棧頂元素,并完成與FSTx相同的功能
FISTx:將棧頂數據從浮點格式轉換為int型后,存入存儲單元
FISTPx:彈出棧頂元素,并完成與FISTx相同的功能不作要求,大概了解一下X87FPU指令數據傳送類(3)交換
FXCH:交換棧頂和次棧頂兩元素(4)常數裝載到棧頂
FLD1:裝入常數1.0
FLDZ:裝入常數0.0
FLDPI:裝入常數pi(=3.1415926...)
FLDL2E:裝入常數log(2)e
FLDL2T:裝入常數log(2)10
FLDLG2:裝入常數log(10)2
FLDLN2:裝入常數Log(e)2X87FPU指令算術運算類(1)加法
FADD/FADDP:
相加/相加后彈出FIADD:按int型相加(2)減法
FSUB/FSUBP:
相減/相減后彈出FSUBR/FSUBRP:調換次序相減/相減后彈出FISUB:按int型相減
FISUBR:按int型相減,調換相減次序
若指令未帶操作數,則默認操作數為ST(0)、ST(1)
帶R后綴指令是指操作數順序變反,例如:
fsub執行的是x-y,fsubr執行的就是y-xX87FPU指令算術運算類(3)乘法
FMUL/FMULP:
相乘/相乘后出棧
FIMUL:按int型相乘(4)除法
FDIV/FDIVP:
相除/相除后出棧
FIDIV:按int型相除
FDIVR/FDIVRP
FIDIVR例如:
fidivl0x8(%ebp)將指定存儲單元操作數M[R[ebp]+8]中的int型數轉換為double型,再將ST(0)除以該數,并將結果存入ST(0)中
IA-32浮點操作舉例
問題:使用老版本gcc–O2編譯時,程序一輸出0,程序二輸出卻是1,是什么原因造成的?f(10)的值是多少?機器數是多少?IA-32浮點操作舉例8048328:55push%ebp8048329:89e5mov%esp,%ebp804832b:d9e8fld1
804832d:da7508fidivl0x8(%ebp)
8048330:c9leave8048331:c3ret
doublef(intx){return1.0/x;}兩條重要指令的功能如下。fld1:將常數1壓入棧頂ST(0)fidivl:將指定存儲單元操作數M[R[ebp]+8]中的int型數轉換為double型,再將ST(0)除以該數,并將結果存入ST(0)中0.1=0.00011[0011]B=0.00011001100110011001100110011…Bf(10)=0.1IA-32浮點操作舉例08048334<main>:8048334:55push%ebp8048335:89e5mov%esp,%ebp8048337:83ec08sub$0x8,%esp804833a:83e4f0and$0xfffffff0,%esp804833d:83ec0csub$0xc,%esp8048340:6a0apush$0xa8048342:e8e1ffffffcall8048328<f>//計算a=f(10)8048347:dd5df8fstpl0xfffffff8(%ebp)//a存入內存804834a:c704240a000000movl$0xa,(%esp)8048351:e8d2ffffffcall8048328<f>//計算b=f(10)8048356:dd45f8fldl0xfffffff8(%ebp)
//a入棧頂8048359:58pop%eax804835a:dae9fucompp//比較ST(0)a和ST(1)b804835c:dfe0fnstsw%ax//把FPU狀態字送到AX804835e:80e445and$0x45,%ah8048361:80fc40cmp$0x40,%ah8048364:0f94c0sete%al8048367:5apop%edx8048368:0fb6c0movzbl%al,%eax804836b:50push%eax804836c:68d8830408push$0x80483d88048371:e8f2feffffcall8048268<_init+0x38>8048376:c9leave8048377:c3ret…a=f(10);b=f(10);i=a==b;…0.1是無限循環小數,無法精確表示,比較時,a舍入過而b沒有舍入過,故a≠b80位→64位64位→80位IA-32浮點操作舉例8048342:e8e1ffffffcall8048328<f>//計算a8048347:dd5df8fstpl0xfffffff8(%ebp)
//把a存回內存
//a產生精度損失
804834a:c704240a000000movl$0xa,(%esp,1)8048351:e8d2ffffffcall8048328<f>//計算b8048356:dd5df0fstpl0xfffffff0(%ebp)//把b存回內存
//b產生精度損失
8048359:c704240a000000movl$0xa,(%esp,1)8048360:e8c3ffffffcall8048328<f>
//計算c8048365:ddd8fstp%st(0)8048367:dd45f8fldl0xfffffff8(%ebp)//從內存中載入a804836a:dd45f0fldl0xfffffff0(%ebp)//從內存中載入b804836d:d9c9fxch%st(1)804836f:58pop%eax8048370:dae9fucompp//比較a,b8048372:dfe0fnstsw%ax…a=f(10);b=f(10);
c=f(10);i=a==b;…0.1是無限循環小數,因而無法精確表示,比較時,a和b都是舍入過的,故a=b!IA-32浮點操作舉例從這個例子可以看出編譯器的設計和硬件結構緊密相關。對于編譯器設計者來說,只有真正了解底層硬件結構和真正理解指令集體系結構,才能夠翻譯出沒有錯誤的目標代碼,并為程序員完全屏蔽掉硬件實現的細節,方便應用程序員開發出可靠的程序。對于應用程序開發者來說,也只有真正了解底層硬件的結構,才有能力編制出高效的程序,能夠快速定位出錯的地方,并對程序的行為作出正確的判斷。IA-32浮點操作舉例1#include<stdio.h>2intfunct(intr){3 return2*3.14*r;4}56intmain(){7 floatx=funct(5.6);8 printf("%f\n",x);9 return0;10}先將上述程序在x87架構上進行編譯、匯編生成可重定位目標文件,然后對可重定位目標文件進行反匯編,根據反匯編結果分析該程序執行過程中進行了哪些類型轉換。IA-32浮點操作舉例1000011ed<funct>:211ed:55push%ebp……#M[R[ebp]+8]←r,ST(0)←2*3.14*r511f3:db4508fildl0x8(%ebp)
611f6:dd0510200000fldl0x2010711fc:dec9fmulp%st,%st(1)……#M
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 27《我堅持我成功》教學設計-2023-2024學年心理健康四年級下冊北師大版
- 18文言文二則《鐵杵成針》教學設計-2023-2024學年統編版語文四年級下冊
- 《冰融化了》教學設計-2024-2025學年科學三年級上冊教科版
- 七年級生物下冊 第三單元 第二章 人的生活需要空氣 第三節 呼吸保健與急救教學設計設計(新版)濟南版
- 2018春蘇科版八年級生物下冊第八單元第24章同步教學設計:8.24.1人體的免疫防線
- 行政工作總結課件
- 2023三年級英語上冊 Unit 4 I have a ball Lesson 20教學設計 人教精通版(三起)
- 9 端午粽 教學設計-2024-2025學年語文一年級下冊統編版
- Unit 2 No Rules No Order Section A(2a~2f)教學設計-2024-2025學年人教版英語七年級下冊
- Unit 9 Section B 2a-2e 教學設計2024-2025學年人教版八年級英語下冊
- 2024游樂新“室”界室內樂園洞察與趨勢研究報告
- 2024年共青團入團積極分子考試題庫及答案
- 2024年大語言模型的能力邊界與發展思考報告
- 高教版2023年中職教科書《語文》(基礎模塊)下冊教案全冊
- 辦公樓外立面節能亮化方案
- 膀胱電切術后護理查房
- 維修電工高級技師培訓計劃與教學大綱
- 川教版四年級《生命.生態.安全》下冊全冊 課件
- 鋼板樁支護施工方案完整版
- 機器學習 試卷2套
- IATF16949-2024 內部審核方案
評論
0/150
提交評論