IA-32指令系統類型


IA-32中的傳送指令

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   

“入棧”(pushw %ax)

“出棧” (popw %ax)

 

 程序由指令序列組成

功能:R[esp]← R[esp]-4,M[R[esp]] ←R[ebp]的實現原理

 

執行下一個指令 

 

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:無符號乘 / 帶符號乘
        DIV/ IDIV:帶無符號除 / 帶符號除

算數運算

 

 IA-32的寄存器組織

 

 

 

功能:R[eax]← R[edx]+R[eax]*1

 

功能:R[eax]← R[edx]+R[eax]*1 (執行后)

 

定點加法指令舉例

假設 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的真值為65515
        FFEA的真值為65535-21=65514≠65530+65515,即溢出
        若是帶符號整數運算,則OF=0說明結果沒有溢出
    驗證:FFFA的真值為-6,FFF0的真值為-16
        FFEA的真值為-22=-6+(-16),結果正確,無溢出

定點乘法指令舉例

假設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(帶符號整數乘)
        =16 × (-000000A0H)
        =FFFFFF60H<<4
        =FFFFF600H
        EAX中的真值為-2560

x87浮點處理指令

 IA-32的浮點處理架構

IA-32的浮點處理架構有兩種
    (1) x87FPU指令集(gcc默認)
    (2) SSE指令集(x86-64架構所用)
• IA-32中處理的浮點數有三種類型
    – float類型:32位 IEEE 754 單精度格式
    – double類型:64位 IEEE 754 雙精度格式
    – long double類型:80位雙精度擴展格式
1位符號位s、15位階碼e(偏置常數為16 383)、1位顯式
首位有效位(explicit leading significant bit)j 和 63位
尾數f。它與IEEE 754單精度和雙精度浮點格式的一個重要的
區別是:它沒有隱藏位,有效位數共64位。

x87 FPU指令

x87 FPU 特指與x86處理器配套的浮點協處理器架構
    – 浮點寄存器采用棧結構
        • 深度為8,寬度為80位,即8個80位寄存器
        • 名稱為 ST(0) ~ ST(7),棧頂為ST(0),編號分別為 0~7
    – 所有浮點運算都按80位擴展精度進行
    – 浮點數在浮點寄存器和內存之間傳送
        • float、double、long double型變量在內存分別用IEEE 754單精度、雙精度和擴展精            
            度表示,分別占32位(4B)、64位(8B)和96位(12B,其中高16位無意義)
        • float、double、long double類型變量在浮點寄存器中都用80位擴展精度表示
        • 從浮點寄存器到內存:80位擴展精度格式轉換為32位或64位
        • 從內存到浮點寄存器: 32位或64位格式轉換為80位擴展精度格式
數據傳送類
(1) 裝入 (轉換為80位擴展精度)
    FLD:將數據從存儲單元裝入浮點寄存器棧頂 ST(0)
    FILD:將數據從int型轉換為浮點格式后,裝入浮點寄存器棧頂
(2) 存儲(轉換為IEEE 754單精度或雙精度)
    FSTx:x為s/l時,將棧頂ST(0)轉換為單/雙精度格式,然后存入存儲單元
    FSTPx:彈出棧頂元素,並完成與FSTx相同的功能
    FISTx:將棧頂數據從int型轉換為浮點格式后,存入存儲單元
    FISTP:彈出棧頂元素,並完成與FISTx相同的功能
    帶P結尾指令表示操作數會出棧,也即ST(1)將變成ST(0)
數據傳送類
(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)2 
算術運算類
(3) 乘法
    FMUL/FMULP: 相乘/相乘后彈出棧
    FIMUL:按int型轉換后相乘
(4) 除法
    FDIV/FDIVP : 相除/相除后彈出棧
    FIDIV:按int型轉換后相除
    FDIVR/FDIVRP:調換次序相除/相減后彈出棧
    FIDIVR:按int型轉換並調換次序相除

IA-32浮點操作舉例

 

 

 

從這個例子可以看出
    – 編譯器的設計和硬件結構緊密相關。
    – 對於編譯器設計者來說,只有真正了解底層硬件結構和真正
理解指令集體系結構,才能夠翻譯出沒有錯誤的目標代碼,
並為程序員完全屏蔽掉硬件實現的細節,方便應用程序員開
發出可靠的程序。
    – 對於應用程序開發者來說,也只有真正了解底層硬件的結構
    ,才有能力編制出高效的程序,能夠快速定位出錯的地方,
    並對程序的行為作出正確的判斷。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM