2020国产成人精品视频,性做久久久久久久久,亚洲国产成人久久综合一区,亚洲影院天堂中文av色

分享

FASM 第二章 - 2.1 x86 體系指令 - xuyibo.org

 ShaneWu 2009-11-03
2.1 x86 體系指令
2.1.1 數(shù)據(jù)傳送指令
2.1.2 類型轉(zhuǎn)換指令
2.1.3 二進(jìn)制算術(shù)指令
2.1.4 十進(jìn)制算術(shù)指令
2.1.5 邏輯指令
2.1.6 控制轉(zhuǎn)移指令
2.1.7 I/O 指令
2.1.8 字符串操作指令
2.1.9 標(biāo)志控制指令
2.1.10 條件操作指令
2.1.11 其他指令
2.1.12 系統(tǒng)指令
2.1.13 FPU 指令
2.1.14 MMX 指令
2.1.15 SSE 指令
2.1.16 SSE2 指令
2.1.17 SSE3 指令
2.1.18 AMD 3DNOW!指令
2.1.19 x86-64長(zhǎng)模式指令

這一章講述了匯編語言指令語法和功能。更多的技術(shù)信息可以閱讀Intel軟件開發(fā)者手冊(cè)。

匯編指令有助記符(指令名稱)和0到3個(gè)操作符組成。如果有大于兩個(gè)的操作符,通常第一個(gè)為目的操作符第二個(gè)為源操作符。每個(gè)操作符都可以為寄存器,內(nèi)存或立即數(shù)(操作符語法見1.2節(jié))。每條指令描述后悔有操作符不同用法的例子。

一些指令用作前綴,可以和其他指令放在同行一起使用,一行也允許有多個(gè)前綴。段寄存器也是指令助記符前綴,但推薦在方括號(hào)中段重寫來替代這些前綴。

mov從源操作符傳送字節(jié),字或雙字道目的操作符。它可以在通用寄存器之間,通用寄存器到內(nèi)存,或從內(nèi)存到通用寄存器間傳送數(shù)據(jù),但不能在內(nèi)存間傳送數(shù) 據(jù)。它也可以在立即數(shù)到通用寄存器或內(nèi)存,段寄存器到通用寄存器或內(nèi)存,通用寄存器或內(nèi)存到段寄存器,控制或調(diào)試寄存器到通用寄存器以及通用寄存器到控制 或調(diào)試寄存器間傳送數(shù)據(jù)。只有當(dāng)源操作符和目的操作符大小相同時(shí)mov才能被匯編。下面是一些例子:

 

mov bx,ax      ; 通用寄存器到通用寄存器
mov [char],al  ; 通用寄存器到內(nèi)存
mov bl,[char]  ; 內(nèi)存到通用寄存器
mov dl,32      ; 立即數(shù)到通用寄存器
mov [char],32  ; 立即數(shù)到內(nèi)存
mov ax,ds      ; 段寄存器到通用寄存器
mov [bx],ds    ; 段寄存器到內(nèi)存
mov ds,ax      ; 通用寄存器到段寄存器
mov ds,[bx]    ; 內(nèi)存到段寄存器
mov eax,cr0    ; 控制寄存器到通用寄存器
mov cr3,ebx    ; 通用寄存器到控制寄存器

xchg置換兩個(gè)操作數(shù)內(nèi)容。它可以用來置換兩個(gè)字節(jié)、字或者雙字操作數(shù)。操作數(shù)的順序并不重要。操作數(shù)可以為兩個(gè)通用寄存器,或者通用寄存器同內(nèi)存。例如:

xchg ax,bx     ; 置換兩個(gè)通用寄存器
xchg al,[char] ; 寄存器和內(nèi)存置換

push遞減堆棧指針(esp寄存器),然后傳送操作數(shù)到esp執(zhí)行的棧頂。操作數(shù)可以為內(nèi)存,通用寄存器,段寄存器或字、雙字立即數(shù)。如果操作數(shù) 為沒有指定大小的立即數(shù)時(shí),匯編器在16位模式下默認(rèn)將當(dāng)作16位值,在32位模式下將當(dāng)作32位值。pushw和pushd助記符為push指令的變 種,分別用來壓入16位,32位大小值到堆棧。如果同行后指定了更多參數(shù)(空格分隔,而非逗號(hào)),將匯編為一串push指令。下面為帶有單一操作符的例 子:

push ax       ; 壓入通用寄存器到堆棧
push es       ; 壓入段寄存器
pushw [bx]    ; 壓入內(nèi)存值
push 1000h    ; 壓入立即數(shù)

pusha壓入8個(gè)通用寄存器的內(nèi)容到堆棧,這條指令沒有操作數(shù)。這條指令有兩個(gè)版本,一個(gè)16位的和一個(gè)32位的,匯編器自動(dòng)根據(jù)當(dāng)前模式生成正 確的版本,但也可以使用pushaw或pushad助記符重寫為只為16位或32位版本。16位版本的這條指令將以以下順序壓入通用寄存 器:ax,cx,dx,bx,壓入ax前的sp值,bp,si和di。32為版本將以相同順序壓入等價(jià)的32位通用寄存器。

pop傳送當(dāng)前棧頂?shù)淖只螂p字到目的操作符,然后遞增esp指向新的棧頂。操作符可以為內(nèi)存,通用寄存器或段寄存器。popw和popd助記符為pop指令的變種,分別用來彈出字或雙字。如果同行后指定了更多參數(shù)(空格分隔,而非逗號(hào))將匯編為一串pop指令。

pop bx        ; 彈出棧頂數(shù)據(jù)到通用寄存器
pop ds        ; 彈出到段寄存器
popw [si]     ; 彈出到內(nèi)存

popa彈出堆棧中由pusha指令壓入的寄存器,將忽略其中保存的sp(或esp)值。使用popaw或popad助記符來強(qiáng)制匯編16位或32位版本的這條指令。

2.1.2 類型轉(zhuǎn)換指令

類型轉(zhuǎn)換指令轉(zhuǎn)換字節(jié)為字,字為雙字,雙字為四字。這些轉(zhuǎn)換可以為符號(hào)擴(kuò)展或零擴(kuò)展的。符號(hào)擴(kuò)展將用符號(hào)位來填充,而零擴(kuò)展將使用0來填充。

cwd和cdq分別用來擴(kuò)展ax和eax大小,并將額外位存儲(chǔ)到dx和edx中。轉(zhuǎn)換將使用符號(hào)擴(kuò)展。這些指令沒有操作數(shù)。

cbw符號(hào)擴(kuò)展al的值到ax,cwde符號(hào)擴(kuò)展ax到eax。這些指令也沒有操作數(shù)。

movsx使用符號(hào)擴(kuò)展將字節(jié)轉(zhuǎn)換為字或雙字,字轉(zhuǎn)換為雙字。movzx類似,只是它使用0擴(kuò)展。源操作數(shù)可以為通用寄存器或內(nèi)存,目的操作數(shù)必須為通用寄存器。例如:

movsx ax,al         ; 字節(jié)寄存器轉(zhuǎn)換為字寄存器
movsx edx,dl        ; 字節(jié)寄存器轉(zhuǎn)換為雙字寄存器
movsx eax,ax        ; 字寄存器轉(zhuǎn)換為雙字寄存器
movsx ax,byte [bx]  ; 字節(jié)內(nèi)存之后為字寄存器
movsx edx,byte [bx] ; 字節(jié)內(nèi)存轉(zhuǎn)換為雙字寄存器
movsx eax,word [bx] ; 字內(nèi)存轉(zhuǎn)換為雙字寄存器

2.1.3 二進(jìn)制算術(shù)指令

add替換目的操作數(shù)的值為源操作數(shù)和目的操作數(shù)的和,并且在溢出時(shí)設(shè)置CF標(biāo)志。操作數(shù)可以為字節(jié),字或雙字。目的操作數(shù)可以為通用寄存器或內(nèi)存,源操作數(shù)可以為通用寄存器或立即數(shù),如果目的操作數(shù)為寄存器也可以為內(nèi)存。

add ax,bx     ; add 寄存器到寄存器
add ax,[si]   ; add 內(nèi)存到寄存器
add [di],al   ; add 寄存器到內(nèi)存
add al,48     ; add 立即數(shù)到寄存器
add [char],48 ; add 立即數(shù)到內(nèi)存

adc和add類似,只是如果設(shè)置CF的話結(jié)果還將遞增1。add后跟著多個(gè)adc指令能用來計(jì)算大于32位值的和。

inc將操作數(shù)值遞增1,它不影響CF。操作數(shù)可以為通用寄存器或內(nèi)存,操作數(shù)大小可以為字節(jié),字或雙字。

inc ax        ; 寄存器值遞增1
inc byte [bx] ; 內(nèi)存值遞增1

sub用目的操作數(shù)值減去源操作數(shù),并且用結(jié)果替換目的操作數(shù)。如果需要借位,將設(shè)置CF。操作數(shù)規(guī)則和add指令相同。

sbb和sub類似,只是如果設(shè)置CF的話結(jié)構(gòu)還將遞減1。操作數(shù)規(guī)則和add質(zhì)量相同。sub后跟著多個(gè)sbb指令能用來計(jì)算大于32位值的差。

dec將操作數(shù)值遞減1,它不影響CF。操作數(shù)規(guī)則和inc指令相同。

cmp用目的操作數(shù)減去源操作數(shù),類似sub指令更新標(biāo)志值,但它不改變?cè)春湍康牟僮鞣?。操作?shù)規(guī)則和sub指令相同。

neg用0減去帶符號(hào)的整數(shù)操作數(shù)。這條指令的效果是將帶符號(hào)的操作數(shù)從正數(shù)變?yōu)樨?fù)數(shù)或者從負(fù)數(shù)變?yōu)檎龜?shù)。操作數(shù)規(guī)則和inc指令相同。

xadd交換目的和源操作數(shù),然后載入兩個(gè)值的和到目的操作數(shù)。操作數(shù)規(guī)則和add指令相同。

所有上面的二進(jìn)制算術(shù)指令都將更新SF,ZF,PF和OF標(biāo)志。SF被設(shè)置為結(jié)果符號(hào)位的值,ZF當(dāng)結(jié)果為0時(shí)設(shè)置為1,PF當(dāng)?shù)?位存在偶數(shù)個(gè)1時(shí)設(shè)置,OF在結(jié)果對(duì)于正數(shù)太大或?qū)τ谪?fù)數(shù)太小(超過符號(hào)位)以放到目的操作數(shù)中時(shí)設(shè)置。

mul計(jì)算無符號(hào)操作數(shù)和累加器的積。如果為8位操作數(shù),將和al計(jì)算積,16位結(jié)果返回到ah和al中。如果4,為16位操作數(shù),將和ax計(jì)算 積,32位結(jié)果返回到dx和ax中。如果為32位操作數(shù),將和eax計(jì)算積,64位結(jié)果返回到edx和eax中。當(dāng)結(jié)果高半部分不為零時(shí)將設(shè)置標(biāo)志CF和 OF,否則將清除該標(biāo)志。操作數(shù)規(guī)則和inc指令相同。

imul執(zhí)行符號(hào)乘法運(yùn)算。這條指令有3種用法。第一種允許一個(gè)操作數(shù),和mul指令類似。第二種有兩個(gè)操作數(shù),此時(shí)將計(jì)算目的操作數(shù)和源操作數(shù)的 積,并將結(jié)果替換目的操作數(shù)。目的操作數(shù)可以為16位或32位通用寄存器,源操作數(shù)可以為通用寄存器,內(nèi)存或立即數(shù)。第三種有3個(gè)操作數(shù),目的操作數(shù)必須 為16位或32位通用寄存器,源操作數(shù)可以為通用寄存器或內(nèi)存,第三種操作數(shù)必須為立即數(shù)。源操作數(shù)乘以立即數(shù)并將結(jié)果保存到目的寄存器。所有上面三種形 式都將計(jì)算出雙倍大小的結(jié)構(gòu),并當(dāng)結(jié)果高半部分不為零時(shí)設(shè)置標(biāo)志CF和OF。所以第二種和第三種形式也能用作無符號(hào)操作數(shù),因?yàn)?,無論操作數(shù)是否為有符號(hào) 無符號(hào),結(jié)果的低半部分是相同的。下面的所有三種形式的乘法指令使用例子:

imul bl         ; 累加器和寄存器
imul word [si]  ; 累加器和內(nèi)存
imul bx,cx      ; 寄存器和寄存器
imul bx,[si]    ; 寄存器和內(nèi)存
imul bx,10      ; 寄存器和立即數(shù)
imul ax,bx,10   ; 寄存器,立即數(shù),值到寄存器
imul ax,[si],10 ; 內(nèi)存,立即數(shù),值到寄存器

div計(jì)算操作數(shù)和累加器無符號(hào)運(yùn)算的商。被除數(shù)(累加器)為兩倍大小的除數(shù)(操作數(shù)),商和余數(shù)和除數(shù)有相同尺寸。如果除數(shù)為8位,被除數(shù)為 ax,商和余數(shù)分別保存到al和ah中。如果除數(shù)為16位,被除數(shù)的商的高半部分從dx獲取,低半部分從ax獲取,商和余數(shù)分別保存到ax和dx中。如果 除數(shù)為32位,被除數(shù)的高半部分從edx獲取,低半部分從eax獲取,商和余數(shù)分別保存到eax和edx中。操作數(shù)規(guī)則和mul指令相同。

idiv計(jì)算操作數(shù)和累加器有符號(hào)運(yùn)算的商。它使用和div指令相同的寄存器,操作數(shù)的規(guī)則也是一樣的。

2.1.4 十進(jìn)制算術(shù)指令

十進(jìn)制算術(shù)指令用來調(diào)整上一節(jié)的二進(jìn)制算術(shù)操作以生成有效的壓縮或未壓縮十進(jìn)制結(jié)果,或調(diào)整輸入為一個(gè)二進(jìn)制算術(shù)操作序列以使該操作能生產(chǎn)一個(gè)有效的壓縮或解壓縮十進(jìn)制結(jié)果。

daa調(diào)整al中兩個(gè)有效壓縮十進(jìn)制操作數(shù)和的值。daa必須跟著兩對(duì)壓縮十進(jìn)制數(shù)(每半字節(jié)一個(gè)點(diǎn))的和來得到一對(duì)有效壓縮十進(jìn)制數(shù)字結(jié)果。如果需要進(jìn)位將設(shè)置CF標(biāo)志。這條指令沒有操作數(shù)。

das調(diào)整al中兩個(gè)有效壓縮十進(jìn)制操作數(shù)差的值。das必須跟著兩對(duì)壓縮十進(jìn)制數(shù)(每半個(gè)字節(jié)一個(gè)點(diǎn))的差來得到一對(duì)有效壓縮十進(jìn)制數(shù)字結(jié)果。如果如要進(jìn)位將設(shè)置CF標(biāo)志。這條指令沒有操作數(shù)。

aaa修改al中的內(nèi)容為有效的未壓縮十進(jìn)制數(shù)字,并將高四位清零。aaa必須跟著al中兩個(gè)有效未壓縮十進(jìn)制操作數(shù)和。如果需要進(jìn)位將設(shè)置CF標(biāo)志并遞增ah的值。這條指令沒有操作數(shù)。

aas修改al的值為一個(gè)有效的未壓縮十進(jìn)制數(shù)據(jù),并將高四位清零。aas必須跟著al中兩個(gè)有效未壓縮十進(jìn)制操作數(shù)差。如果需要進(jìn)位將設(shè)置CF標(biāo)志并遞減ah的值。這條指令沒有操作數(shù)。

aam修正兩個(gè)有效未壓縮十進(jìn)制數(shù)的積。aam必須跟著兩個(gè)十進(jìn)制數(shù)字的積來生成一個(gè)有效的十進(jìn)制結(jié)果。數(shù)字的高位在ah中,低位在al 中。這條指令用來調(diào)整ax來生成兩個(gè)任何基數(shù)的未壓縮數(shù)字。標(biāo)志版本的這條指令沒有操作數(shù),另一種有一個(gè)操作數(shù) - 一個(gè)指定創(chuàng)建數(shù)字基數(shù)的立即數(shù)。

aad修改ah保存的分子和ah和ah中兩個(gè)有效未壓縮十進(jìn)制操作數(shù)的商,所以計(jì)算的商將為一個(gè)未壓縮十進(jìn)制數(shù)據(jù)。ah為高位,al為低位。這條指令調(diào)整al的值,結(jié)果也在al中,而ah內(nèi)容為0.這條指令用來調(diào)整任何基數(shù)的兩個(gè)未壓縮數(shù)字。操作數(shù)規(guī)則和aam質(zhì)量相同。

2.1.5 邏輯指令

not將指定操作數(shù)求反。它不影響標(biāo)志。操作數(shù)規(guī)則和inc指令相同。

and,or和xor質(zhì)量執(zhí)行標(biāo)準(zhǔn)的邏輯操作。它們更新標(biāo)志SF,ZF和PF。操作數(shù)規(guī)則和add指令相同。

bt,bts,btr和btc指令只能處理一個(gè)在內(nèi)存或寄存器中的位。該位位置由操作數(shù)的低位指定。偏移有第二個(gè)操作數(shù)指定,它可以為字節(jié)立即數(shù)或 一個(gè)通用寄存器。這些指令首先將選擇的位送到標(biāo)志CF。bt指令不會(huì)做更多操作,bts設(shè)置選擇位為1,btr將選擇為置為0,btc修改將改位值求反。 第一個(gè)操作數(shù)可以為字或雙字。

bt ax,15         ; 測(cè)試寄存器中的位
bts word [bx],15 ; 測(cè)試并設(shè)置內(nèi)存值中的位
btr ax,cx        ; 測(cè)試并重置寄存器中的位
btc word [bx],cx ; 測(cè)試并求反內(nèi)存值中的位

bsf和bsr質(zhì)量掃描字或雙字第一個(gè)為1的位,并將改為索引保存到必須為通用寄存器的目的操作數(shù)。源操作數(shù)可以為通用寄存器或內(nèi)存。當(dāng)整個(gè)串為0 時(shí)設(shè)置ZF標(biāo)志;否則將置為0。如果沒有找到為1的位,謎底寄存器的值為未定義的。bsf從低位到高位掃描(從位索引0開始)。bsr從高位到低位掃描 (16位時(shí)從第15位,32位時(shí)從31位開始)。

bsf ax,bx        ; 向前掃描寄存器
bsr ax,[si]      ; 逆向掃描內(nèi)存值

shl左移目的操作數(shù)為第二個(gè)操作數(shù)指定的位數(shù)。目的操作數(shù)可以為字節(jié),字,或雙字通用寄存器或內(nèi)存。第二個(gè)操作數(shù)可以為立即數(shù)或cl寄存器。左移的最后一位將被放到標(biāo)志CF中。sal和shl為相同指令。

shl al,1         ; 左移寄存器一位
shl byte [bx],1  ; 左移內(nèi)存值一位
shl ax,cl        ; 左移寄存器為cl中的值
shl word [bx],cl ; 左移內(nèi)存值為cl中的值

shr和sar右移目的操作數(shù)為第二個(gè)參數(shù)指定的位數(shù)。操作數(shù)規(guī)則和shl指令相同。shr右移的最后一位將放到標(biāo)志CF中。sar保留操作數(shù)符號(hào)位,如果操作數(shù)為正數(shù)用0左移,否則用1左移。

shld左移目的操作數(shù)(第二個(gè)操作數(shù))為第三個(gè)操作數(shù)指定的位數(shù),lefto do。目的操作數(shù)為字或雙字通用寄存器或內(nèi)存,源操作數(shù)必須為通用寄存器,第三個(gè)操作數(shù)可以為立即數(shù)或cl寄存器。

shld ax,bx,1      ; 左移寄存器1位
shld [di],bx,1    ; 左移內(nèi)存值一位
shld ax,bx,cl     ; 左移寄存器為cl中的位數(shù)
shld [di],bx,cl   ; 左移內(nèi)存值為cl中的位數(shù)

shrd右移目的操作數(shù),lefto to do。不修改源操作數(shù)。操作數(shù)規(guī)則和shld指令相同。

rol和rcl左轉(zhuǎn)字節(jié),字或雙字目的操作數(shù)為第二個(gè)操作數(shù)指定的位數(shù)。對(duì)于每次轉(zhuǎn)動(dòng),左轉(zhuǎn)出來的位數(shù)將成為這個(gè)值新的低位。rcl指令還將把高位放到標(biāo)志CF中。操作數(shù)規(guī)則和shl指令相同。

ror和rcr右轉(zhuǎn)字節(jié),字或雙字目的操作數(shù)為第二個(gè)操作數(shù)指定的位數(shù)。對(duì)于每次轉(zhuǎn)東,右轉(zhuǎn)出來的位數(shù)將成為這個(gè)值新的高位。rcr指令還將把低位放到標(biāo)志CF中。操作數(shù)規(guī)則和shl質(zhì)量相同。

test執(zhí)行和and指令相同的操作,但它不會(huì)修改目的操作數(shù)的值,只更新標(biāo)志。操作數(shù)規(guī)則和and指令相同。

bswap翻轉(zhuǎn)32位通用寄存器:0到7位翻轉(zhuǎn)為23到31位,8到15位翻轉(zhuǎn)為16位到23位。這條指令用來轉(zhuǎn)換little-endian值為big-endian格式,反之亦然。

bswap edx        ; 翻轉(zhuǎn)寄存器值

2.1.6 控制轉(zhuǎn)移指令

jmp無條件轉(zhuǎn)移控制到目的位置。目的地址可以直接在指令中指定或間接通過寄存器或內(nèi)存,允許的地址大小取決于跳轉(zhuǎn)類型為near或far(通過在 操作數(shù)前指定near或far操作數(shù)來指定)以及指令是否為16位或32位。對(duì)于16位指令near跳轉(zhuǎn)操作數(shù)為16位,32位指令為32位。16位 far跳轉(zhuǎn)操作數(shù)大小為32位,32位指令為64位。一個(gè)直接jmp指令 包括作為指令一部分的目的地址(可以包含short,near或far操作符),指定地址的操作數(shù)對(duì)于near或短跳轉(zhuǎn)為數(shù)值表達(dá)式,對(duì)于far跳轉(zhuǎn)為兩 個(gè)用冒號(hào)分隔的數(shù)值表達(dá)式。第一個(gè)指定段選擇子,第二個(gè)為段中偏移。pword操作符可強(qiáng)制為32位far調(diào)用,dword強(qiáng)制為16位far調(diào)用。間接 jmp指令間接從寄存器或指針變量中獲取目的地址,操作數(shù)應(yīng)為通用寄存器或內(nèi)存。細(xì)節(jié)見1.2.5節(jié)。

jmp 100h       ; 直接near跳轉(zhuǎn)
jmp 0FFFFh:0   ; 直接far跳轉(zhuǎn)
jmp ax         ; 間接near跳轉(zhuǎn)
jmp pword [ebx]; 間接far跳轉(zhuǎn)

call轉(zhuǎn)移控制到過程,保存call后指令地址到堆棧,稍后將被ret(返回)指令使用。操作數(shù)規(guī)則和jmp指令相同,但call沒有直接種類因此它不是最優(yōu)的。

ret,retn和retf指令結(jié)束過程執(zhí)行將轉(zhuǎn)移控制給堆棧中call指令壓入的地址。ret等價(jià)于retn,retn從near調(diào)用過程返回, 而retf從far調(diào)用過程返回。這些指令默認(rèn)地址大小和當(dāng)前代碼設(shè)置適合,但也可以使用retw,retnw和retfw助記符來強(qiáng)制大小為16位,使 用retd,retnd和retfd助記符強(qiáng)制大小為32位。這些指令可可選的指定一個(gè)立即數(shù)操作數(shù),用它和堆棧指針相加,它的作用是在執(zhí)行call指令 之前移除調(diào)用程序壓入堆棧的參數(shù)。

iret返回控制到中斷過程。它不同于ret的地方是它還將彈出堆棧中的標(biāo)志到標(biāo)志寄存器。這個(gè)標(biāo)志是由中斷機(jī)制保存的。它默認(rèn)返回地址為當(dāng)前代碼設(shè)置,但也可以使用iretw或iretd助記符來強(qiáng)制使用16位或32位。

條件轉(zhuǎn)移指令根據(jù)指令執(zhí)行時(shí)CPU標(biāo)志狀態(tài)來決定是否轉(zhuǎn)移控制。條件跳轉(zhuǎn)助記符可以通過j助記符后面跟著表格2.1列出的條件助記符來得到,例如 jc指令在CF設(shè)置時(shí)轉(zhuǎn)移控制。條件跳轉(zhuǎn)可以為short或near,僅能直接跳轉(zhuǎn),并且能優(yōu)化(見1.2.5),操作數(shù)為指定目的地址的立即數(shù)。

loop指令為使用cx(或ecx)中指定軟循環(huán)次數(shù)的條件跳轉(zhuǎn)。所有l(wèi)oop指令自動(dòng)遞減cx(或ecx),并且在cx(或ecx)為0時(shí)結(jié)束循 環(huán)。使用cx還是ecx取決于當(dāng)前代碼設(shè)置為16位還是32為,但也可以使用loopw助記符強(qiáng)制使用cx或使用loopd助記符強(qiáng)制使用ecx。 loope和loopz是相同指令,用作標(biāo)準(zhǔn)loop,但它也在ZF為1時(shí)結(jié)束循環(huán)。loopew和loopzw強(qiáng)制使用cx寄存器,looped和 loopzd強(qiáng)制使用ecx寄存器。loopne和loopnz是相同指令,用作標(biāo)準(zhǔn)loop,但它也在ZF為0時(shí)結(jié)束循環(huán)。loopnew和 loopnzw助記符強(qiáng)制使用cx寄存器,loopned和loopnzd強(qiáng)制使用ecx寄存器。每一個(gè)loop指令都需要一個(gè)立即數(shù)值來指定目的地址, 它只能為短調(diào)整(跟在loop指令前128字節(jié)和指令后127字節(jié)范圍)。

jcxz在cx值為0時(shí)跳到指定標(biāo)號(hào),jecxz類似,但在ecx為0時(shí)跳到指定標(biāo)號(hào)。操作數(shù)規(guī)則和loop指令類似。

int激活操作數(shù)指定的中斷服務(wù)過程,中斷號(hào)范圍在0到255之間。中斷服務(wù)過程以iret指令結(jié)束,返回控制給int后的指令。int3助記符為短格式的調(diào)用中斷3的指令。into指令當(dāng)OF為1的話調(diào)用中斷。

bound檢查指定寄存器中的符號(hào)值是否在指定范圍內(nèi)。如果不在這個(gè)范圍將產(chǎn)生中斷5。它需要兩個(gè)參數(shù),第一個(gè)操作數(shù)為要測(cè)試的寄存器,第二個(gè)操作數(shù)為范圍。操作數(shù)大小為word或dword。

bound ax,[bx]  ; 檢查word數(shù)據(jù)邊界
boudn eax,[esi]; 檢查dword數(shù)據(jù)邊界
助記符 測(cè)試條件 描述
o OF=1 溢出
no OF=0 不溢出
c
b
nae
CF=1 進(jìn)位
小于
不大于
nc
ae
nb
CF=0 不進(jìn)位
不大于
不小于
e
z
ZF=1 相等
ne
nz
ZF=0 不相等
不為0
be
na
CF或ZF=1 小于或等于
不大于
a
nbe
CF或ZF=0 大于
不小于不等于
s SF=1 有符號(hào)
ns SF=0 <無符號(hào)/td>
p
pe
PF=1 偶校驗(yàn)
np
po
PF=0 奇校驗(yàn)
l
nge
SF異或OF=1 小于
不大于不等于
ge
nl
SF異或OF=0 大于或等于
不小于
le
ng
(SF異或OF)或ZF=1 小于或等于
不大于
g
nle
(SF異或OF)或ZF=0 大于
不小于不等于
表2.1:條件

2.1.7 I/O 指令

in從輸入端口傳輸字節(jié),字或雙字到al,ax,或eax。I/O端口可以用與指令一起編碼的字節(jié)立即數(shù)直接尋址,或間接使用dx寄存器。目的操作數(shù)為al,ax或eax寄存器。源操作數(shù)應(yīng)當(dāng)為0到255之間的立即數(shù),或dx寄存器。

in al,20h      ; 從端口20h輸入字節(jié)
in ax,dx       ; 從dx尋址的端口輸入字

out傳送字節(jié),字,或者雙字到al,ax,或eax指定的輸出端口。程序可以使用與in指令相同的方法指定端口號(hào)。目的操作數(shù)應(yīng)當(dāng)為0到255之間的立即數(shù),或dx寄存器。源操作數(shù)應(yīng)為al,ax或eax寄存器。

out 20h,ax     ; 輸出字道端口20h
out dx,al      ; 輸出字節(jié)到dx尋址的端口

2.1.8 字符串操作指令

字符串操作針對(duì)字符串的一個(gè)元素。字符串元素可以為字節(jié),字或雙字。字符串元素用si和di(或esi和edi)尋址。每次字符串操作后si和或 di(或esi和或edi)自動(dòng)更新指向字符串中后一個(gè)元素。如果DF(方向標(biāo)志位)為0,將遞增索引寄存器,否則將遞減。取決于字符串元素的大小在遞增 或遞減大小為1,2或4。每一個(gè)字符串操作指令都有不使用任何操作數(shù)的簡(jiǎn)短格式,在16位下使用si或和di,在32位下使用esi或和edi。si和 esi默認(rèn)從ds段中定位數(shù)據(jù),di和edi默認(rèn)從es段中定位數(shù)據(jù)。當(dāng)字符串操作助記符后跟著指定字符串元素大小的字母時(shí)將使用短格式,“b”為字節(jié)元 素,“w”為字元素,“d”為雙字元素。字符串操作完整格式需要指定尺寸操作符和內(nèi)存地址的操作數(shù),操作數(shù)可以為跟有任何段前綴的si或esi,di或 edi通常和es段前綴使用。

movs傳送si(或esi)指向的字符串元素到di(或edi)指向的地址。操作數(shù)尺寸可以為byte,word或dword。目的操作數(shù)應(yīng)當(dāng)為di或edi尋址的內(nèi)存,源操作數(shù)應(yīng)當(dāng)為跟著任何段前綴si或esi尋址的內(nèi)存。

movs byte [di],[si]       ; 傳送字節(jié)
movs word [es:di],[ss:si] ; 傳送字
movsd                     ; 傳送雙字

cmps用目的字符串元素減去源字符串元素并更新標(biāo)志AF,SF,PF,CF和OF,但它不會(huì)修改任何比較元素。如果字符串元素相當(dāng),ZF設(shè)置為1,否則為0。第一個(gè)操作數(shù)為帶有任何段前綴的si或esi定位的源字符串元素,第二個(gè)操作數(shù)為di或edi定位的目的字符串。

cmpsb                     ; 比較字節(jié)
cmps word [ds:si],[es:di] ; 比較字
cmps dword [fs:esi],[edi] ; 比較雙字

scas用al,ax,或eax(取決于字符串元素的尺寸)減去目的字符串元素并更新標(biāo)志AF,SF,ZF,PF,CF和OF。如果值相等,ZF將設(shè)置為1,否則為0.操作數(shù)因?yàn)閐i或edi定位的目的字符串元素。

scas byte [es:di]         ; scan 字節(jié)
scasw                     ; scan 字
scas dword [es:edi]       ; scan 雙字

lods載入字符串元素到al,ax,或eax。操作數(shù)因?yàn)閹в腥魏味吻熬Y的si或esi尋址的字符串元素。

lods byte [ds:si]         ; load 字節(jié)
lods word [cs:si]         ; load 字
lodsd                     ; load 雙字

stos將al,ax,或eax的值放到目的字符串元素。字符串規(guī)則和scas指令相同。

ins從dx尋址的輸入端口傳送一個(gè)字節(jié),字或者雙字到目的字符串元素。目的操作數(shù)應(yīng)當(dāng)為di或edi尋址的內(nèi)存,源操作數(shù)應(yīng)當(dāng)為dx寄存器。

insb                      ; input 字節(jié)
ins word [es:di],dx       ; input 字
ins dword [edi],dx        ; input 雙字

outs傳送源字符串元素到dx寄存器尋址的輸出端口。目的操作數(shù)應(yīng)當(dāng)dx寄存器,源操作數(shù)應(yīng)當(dāng)為帶有可帶有任何段前綴的si或esi尋址的內(nèi)存。

outs dx,byte [si]         ; output 字節(jié)
outsw                     ; output 字
outs dx,dword [gs:esi]    ; output 雙字

重復(fù)前綴rep,repe/repz,和repne/repnz指定重復(fù)字符串操作。當(dāng)一個(gè)字符串操作指令包含重復(fù)前綴時(shí),操作將重復(fù)執(zhí)行,每一次 將使用不同的字符串元素。當(dāng)前綴指定的一個(gè)條件滿足時(shí)結(jié)束重復(fù)。每次操作后所有3個(gè)前綴自動(dòng)遞減cx或ecx寄存器(取決于是否字符串操作指令使用16位 或32位尋址),并且重復(fù)指定的操作指導(dǎo)cx或ecx為0。repe/repz和repne/repnz僅和scas和cmps指令使用(下面講述的)。 當(dāng)使用這些前綴時(shí),取決于ZF標(biāo)志重復(fù)后面的指令,此外,當(dāng)ZF為0時(shí)repe和repz結(jié)束執(zhí)行,當(dāng)ZF為1時(shí),repne和repnz結(jié)束執(zhí)行。

rep movsd                 ; 傳送多個(gè)雙字
repe cmpsb                ; 比較字節(jié)直到不相等

2.1.9 標(biāo)志控制指令

標(biāo)志控制指令用來直接修改標(biāo)志寄存器中的狀態(tài)位。這節(jié)講述的所有指令都沒有操作數(shù)。

stc設(shè)置進(jìn)位標(biāo)志CF為1,clc清零CF,cmc逆反CF的值。std設(shè)置方向標(biāo)志DF為1,cld清零DF,sti設(shè)置中斷標(biāo)志IF為1以允許中的,cli清零IF以禁止中斷。

lahf拷貝SF,ZF,AF,PF,和CF到ah寄存器的位7,6,4,2,和0。其余位將不受影響。 標(biāo)志位保持不變。

sahf將ah的位7,6,2,和0傳送到SF,ZF,AF,PF,和CF。

pushf將esp值遞減2或4,壓入低16位或32位的符號(hào)寄存器到堆棧,壓入數(shù)據(jù)大小取決于當(dāng)前代碼設(shè)置。pushfw強(qiáng)制壓入16位,pushfd強(qiáng)制壓入32位。

popf從棧頂彈出16位或32位數(shù)據(jù)到符號(hào)寄存器,然后遞減esp值為2或4,遞減大小取決于當(dāng)前代碼設(shè)置。popfw強(qiáng)制彈出16位,popfd強(qiáng)制彈出32位。

2.1.10 條件操作指令

這些指令有set助記符,條件助記符(見表2.1)組成,如果條件為true設(shè)置一個(gè)字節(jié)為1否則為置為0。操作數(shù)必須為8位的通用寄存器或內(nèi)存中字節(jié)。

setne al       ; 如果ZF為0設(shè)置al
seto byte [bx] ; 如果溢出設(shè)置byte

salc指令當(dāng)CF為0時(shí)設(shè)置al的所有位為1,否則都置為0.這條指令沒有參數(shù)。

cmov助記符后面跟著條件助記符組成的指令,僅當(dāng)條件滿足時(shí)傳送通用寄存器中的word或dword到通用寄存器。目的操作數(shù)必須為通用寄存器,源操作數(shù)可以為通用寄存器或內(nèi)存。

cmove ax,bx      ; 當(dāng)ZF為1時(shí)傳送
cmovnc eax,[ebx] ; 當(dāng)CF為0時(shí)傳送

cmpxchg比較al,ax或eax和目的操作數(shù)。如果兩個(gè)值相等,源操作數(shù)載入到目的操作數(shù),否則目的操作數(shù)載入到al,ax或eax寄存器。目的操作數(shù)可以為通用寄存器或內(nèi)存,源操作數(shù)必須為通用寄存器。

cmpxchg dl,bl    ; 和寄存器比較并交換
cmpxchg [bx],dx  ; 和內(nèi)存比較并交換

cmpxchg8b比較edx和eax組成的64位值和目的操作數(shù)比較。如果值相等,ecx和ebx中64位值將保存到目的操作數(shù)。否則目的操作數(shù)值保存到edx和eax寄存器。目的寄存器必須為內(nèi)存中的qword。

cmpxchg8b [bx]   ; 比較并交換8字節(jié)

2.1.11 其他指令

nop指令占用一個(gè)字節(jié)但除了指令指針外沒有任何作用。這條指令沒有操作數(shù),不會(huì)執(zhí)行任何操作。

ud2指令生成一個(gè)無效的指令異常。這條指令用作軟件測(cè)試來顯式字生成一個(gè)無效指令。這條指令沒有操作數(shù)。

xlat替換al寄存器字節(jié)為bx或ebx尋址的轉(zhuǎn)換表中al索引的字節(jié)。操作數(shù)必須為可帶有任何段前綴的bx或ebx尋址的內(nèi)存中一個(gè)字節(jié)。這條指令有一個(gè)沒有任何操作數(shù)的短格式xlatb,它使用ds段寄存器中bx或ebx(取決于當(dāng)前代碼設(shè)置)中的地址。

lds轉(zhuǎn)移源操作數(shù)中的指針變量到ds和目的寄存器。源操作數(shù)必須為內(nèi)存操作數(shù),目的寄存器必須為通用寄存器。ds寄存器接受段選擇子,目的寄存器 接受指針偏移部分。les,lfs,lgs和lss操作和lds類似,只是它們分別使用es,fs,gs和ss寄存器,而不是ds寄存器。

lds bx,[si]      ; 載入指針到ds:bx

lea傳輸源操作數(shù)偏移(而不是值)到目的寄存器。源操作數(shù)必須為內(nèi)存操作數(shù),目的寄存器必須為同一寄存器。

lea dx,[bx+si+1] ; 載入有效地址到dx

cpuid返回處理器標(biāo)識(shí)和特性信息到eax,ebx,ecx和edx寄存器。指令執(zhí)行前eax寄存器為參數(shù)。該指令沒有操作數(shù)。

pause指令延遲指定時(shí)間執(zhí)行下一條指令。它可用來提高死等效率。這條指令沒有操作數(shù)。

enter創(chuàng)建堆??蚣埽捎米鲗?shí)現(xiàn)塊結(jié)構(gòu)高級(jí)語言的范圍規(guī)則。leave指令在過程結(jié)束后和過程開頭的enter一起用來簡(jiǎn)化堆棧管理,并用作嵌 套過程中控制訪問變量。enter指令有兩個(gè)參數(shù)。第一個(gè)指定堆棧中要分配的動(dòng)態(tài)存儲(chǔ)字節(jié)大小。第二個(gè)參數(shù)為相應(yīng)嵌套層數(shù),范圍為0到31。指定層數(shù)決定 了多少堆??蚣苤羔槒那懊嬉粋€(gè)框架中拷貝新的堆棧框架。堆??蚣芡ǔ=凶鲲@示。顯示的第一個(gè)word(當(dāng)代碼為32位時(shí)為dword)為最后的堆??蚣堋? 這個(gè)指針允許leave指令通過廢棄上一個(gè)堆棧幀來逆向前面的enter指令動(dòng)作。當(dāng)enter為過程創(chuàng)建一個(gè)新的顯示后,通過遞減esp為指定字節(jié)來分 配需要的動(dòng)態(tài)存儲(chǔ)空間。允許過程尋址顯示,enter保留bp(后ebp)指向新堆??蚣堋H绻短讓訑?shù)為0,enter壓入bp(或ebp),拷貝sp 到bp(或esp到ebp),然后esp遞減第一個(gè)操作數(shù)大小。對(duì)于嵌套層數(shù)大于0的,處理器在調(diào)整堆棧指針前壓入額外的框架指針。

enter 2048,0

2.1.12 系統(tǒng)指令

lmsw載入操作數(shù)到機(jī)器狀態(tài)字(CR0的0到15位),而smsw保存機(jī)器狀態(tài)字到目的操作數(shù)。這兩條指令操作數(shù)可以為16位通用寄存器,對(duì)于smsw還可以為32位通用寄存器。

lmsw ax      ; 從寄存器載入機(jī)器狀態(tài)字
smsw [bx]    ; 載入機(jī)器狀態(tài)字到內(nèi)存

lgdt和lidt指令分別用來載入操作數(shù)中的值到全局描述表寄存器和中斷描述表寄存器。sgdt和sidt分別用來保存全局描述表或中斷描述表寄存器到目的操作數(shù)。操作數(shù)必須為內(nèi)存中的6個(gè)字節(jié)。

lgdt [ebx]   ; 載入全局描述表

lldt載入操作數(shù)到局部描述表寄存器的選擇子,sldt保存局部描述表寄存器段選擇子到操作數(shù)。ltr載入操作數(shù)到任務(wù)寄存器段選擇子,str保存任務(wù)寄存器選擇子到操作數(shù)。操作數(shù)規(guī)則和lmsw,smsw指令相同。

lar載入源操作數(shù)指定的選擇子對(duì)應(yīng)的段描述符訪問權(quán)限到目的操作數(shù),并設(shè)置ZF標(biāo)志。目的操作數(shù)可以為16位或32為通用寄存器。源操作數(shù)必須為16位通用寄存器或內(nèi)存。

lar ax,[bx]  ; 載入訪問權(quán)限到word
lar eax,dx   ; 載入訪問權(quán)限到dword

lsl從源操作數(shù)選擇子指定的段描述符的段限制到目的操作數(shù)并設(shè)置ZF標(biāo)志。操作數(shù)規(guī)則和lar指令相同。

verr和verw檢查操作數(shù)指定代碼或數(shù)據(jù)段是否能以當(dāng)前特權(quán)級(jí)上讀或?qū)?。操作?shù)必須為word,可以為通用寄存器或內(nèi)存。如果可用段并且可讀(對(duì)于verr)或可寫(對(duì)于verw),將設(shè)置ZF為1,否者ZF置為0。操作數(shù)規(guī)則和lldt指令相同。

arpl比較兩個(gè)段選擇子的RPL(請(qǐng)求特權(quán)級(jí))。第一個(gè)操作數(shù)包含一個(gè)段選擇子,第二個(gè)包含另一個(gè)。如果目的操作數(shù)RTL小于源操作數(shù)的RPL,ZF置為1,否則置為0,這條指令不影響目的操作數(shù)。目的操作數(shù)可以為16位通用寄存器或內(nèi)存,源操作數(shù)必須為通用寄存器。

arpl bx,ax   ; 調(diào)整寄存器選擇子RPL
arpl [bx],ax ; 調(diào)整內(nèi)存選擇子RPL

clts清零CR0寄存器的任務(wù)切換TS位。這條指令沒有操作數(shù)。

lock前綴導(dǎo)致處理器在執(zhí)行該指令期間斷言總線鎖定信號(hào),總線鎖定信號(hào)保證處理器在信號(hào)斷言期間獨(dú)占使用任何共享內(nèi)存。lock前綴只能用在以下 指令,并且目的操作數(shù)為內(nèi) 存:add,adc,and,btc,btr,bts,cmpxchg,cmpxchg8b,dec,inc,neg,not,or,sbb,sub,xor,xadd 和xchg。如果lock前綴和上面其中一指令使用并且源操作數(shù)為內(nèi)存,可能會(huì)產(chǎn)生未定義指令異常。一個(gè)未定義指令異常也可能在lock和不在上面列出的 指令一起使用的時(shí)候產(chǎn)生。xchg指令常用來斷言總線鎖定信號(hào)無論是否使用lock前綴。

invlpg無效(寫)操作數(shù)指定的轉(zhuǎn)換后援緩沖項(xiàng)TLB。處理器定位這些地址包含的頁并為這些頁回寫TLB項(xiàng)。

rdmsr載入64位MSR(model specific register)ecx中的地址到edx和eax。wrmsr寫edx和eax到ecx寄存器指定的64位MSR。rdtsc從64位MSR載入當(dāng)前處 理器時(shí)間戳到edx和eax寄存器。處理器每一時(shí)鐘周期遞增MSR時(shí)間戳,每次處理器重置時(shí)重置時(shí)間戳為0。rdpmc載入edx寄存器指定的40位性能 監(jiān)視計(jì)數(shù)器到edx和eax。這些指令沒有操作數(shù)。

wbinvd回寫處理器內(nèi)部緩沖中所有修改的緩沖行到主內(nèi)存,并且無效內(nèi)部緩沖。然后創(chuàng)建一個(gè)特殊函數(shù)總線周期來指導(dǎo)外部緩沖也回寫外部修改數(shù)據(jù)以及另一個(gè)時(shí)鐘周期來標(biāo)識(shí)外部緩沖無效。這條指令沒有操作數(shù)。

rsm從系統(tǒng)管理模式返回到當(dāng)處理器接受SMM中斷時(shí)所處的模式。這條指令沒有操作數(shù)。

sysenter執(zhí)行到ring 0系統(tǒng)過程的快速調(diào)用,sysexit執(zhí)行到ring 3的快速返回。這些指令是否可用有MSR相關(guān)位標(biāo)識(shí)。這些指令沒有操作數(shù)。

2.1.13 FPU 指令

浮點(diǎn)單元FPU指令操作三種格式的浮點(diǎn)數(shù)據(jù):?jiǎn)尉龋?2位),雙精度(64位)和擴(kuò)展雙精度(80位)。FPU寄存器構(gòu)成一個(gè)堆棧,并且它們都是 擴(kuò)展雙精度的。當(dāng)從堆棧中壓入或彈出一些值時(shí),F(xiàn)PU寄存器移動(dòng),所以st0一直為FPU堆棧棧頂?shù)闹?,st1為棧頂下的第一個(gè)值。st0和st是同義 詞。

fld壓入浮點(diǎn)數(shù)據(jù)到FPU寄存器堆棧。操作數(shù)可以為32位,64位或80位內(nèi)存地址或FPU寄存器,其值將稍后載入到FPU寄存器堆棧棧頂(也就是st0寄存器),并且自動(dòng)轉(zhuǎn)換為擴(kuò)展雙精度格式。

fld dword [bx]       ; 從內(nèi)存載入單精度浮值。
fld st2              ; 壓入st2的值到寄存器堆棧

fld2,fldz,fldl2t,fldl2e,fldpi,fldlg2和fldln2載入常用的常量到FPU寄存器堆棧。載入的常量分別為:+1.0,+0.0,log2|10,log2|e,pi,log10|2和ln2。這些指令沒有操作數(shù)。

fild轉(zhuǎn)換一個(gè)源操作數(shù)整數(shù)為擴(kuò)展雙精度浮點(diǎn)格式,并將結(jié)果壓入FPI寄存器堆棧。源操作數(shù)可以為16位,32位,或64位內(nèi)存地址。

fild qword [bx]      ; 從內(nèi)存載入64位整數(shù)

fst拷貝st0寄存器的值到目的操作數(shù),目的操作數(shù)可以為32位或64位內(nèi)存地址或另一個(gè)FPU寄存器。fstp執(zhí)行和fst相同的操作,只是它還將彈出寄存器堆棧。fstp執(zhí)行和fst相同的操作,只是它還將壓入一個(gè)80位內(nèi)存中的值。

fst st3              ; 拷貝st0值到st3寄存器
fstp tword [bx]      ; 存儲(chǔ)內(nèi)存中值并彈出堆棧

fist轉(zhuǎn)換st0值為一整數(shù),并保存結(jié)果到目的操作數(shù)。操作數(shù)可以為61位或32位內(nèi)存地址。fistp執(zhí)行相同操作,但很將彈出寄存器堆棧,并能存儲(chǔ)值到64位內(nèi)存,操作數(shù)規(guī)則和fild指令相同。

fbld轉(zhuǎn)換壓縮BCD整數(shù)為擴(kuò)展雙精度浮點(diǎn)格式并壓入值到FPU堆棧。fbstp轉(zhuǎn)換st0中的值為18個(gè)數(shù)字壓縮BCD整數(shù),保存結(jié)果到目的操作數(shù)并彈出寄存器堆棧。操作數(shù)應(yīng)為80位內(nèi)存地址。

fadd計(jì)算目的和源操作數(shù)的和并保存結(jié)果到目的操作數(shù)。目的操作數(shù)一直為FPU寄存器,如果源操作數(shù)為內(nèi)存地址,目的操作數(shù)為st0寄存器并且只指定源操作數(shù)。內(nèi)存操作數(shù)可以為32位或64位值。

fadd qword [bx]      ; 計(jì)算擴(kuò)展雙精度和st0的和
fadd st2,st0         ; 計(jì)算st0和st2的和

faddp計(jì)算目的和源操作數(shù)的和,并保持結(jié)果到目的位置,然后彈出堆棧。目的操作數(shù)必須為FPU寄存器,源操作數(shù)必須為st0。當(dāng)沒有指定操作數(shù)時(shí),將使用st1作為目的操作數(shù)。

faddp                ; 計(jì)算st0和st1的和并彈出堆棧
faddp st2,st0        ; 計(jì)算st0和st2的和并彈出堆棧

fiadd指令轉(zhuǎn)換源操作數(shù)整數(shù)為擴(kuò)展雙精度浮點(diǎn)數(shù),并和目的操作數(shù)相加。操作數(shù)必須為16位或32位內(nèi)存地址。

fiadd word[bx]       ; word整數(shù)和st0相加

fsub,fsubr,fmul,fdiv,fdivr指令和fadd類似,操作數(shù)規(guī)則和fadd相同。fsub計(jì)算目的操作數(shù)和源操作數(shù)的 差,fsubr計(jì)算源操作數(shù)和目的操作數(shù)的差,fmul將目的和源操作數(shù)相乘。fdivr計(jì)算目的操作數(shù)和源操作數(shù)的差,fdivr計(jì)算源操作數(shù)和目的操 作數(shù)的差。fsubp,fsubrp,fmulp,fdivp,fidivr在轉(zhuǎn)換源操作數(shù)整數(shù)為浮點(diǎn)數(shù)據(jù)后執(zhí)行這些操作,它們操作數(shù)的規(guī)則和fiadd 指令相同。

fsqrt計(jì)算st0寄存器中值的開方。fsin計(jì)算值的sin,fabs清除符號(hào)位來得到絕對(duì)值,frndint根據(jù)當(dāng)前四舍五入模式來得到最接 近的整數(shù)值。f2xm1計(jì)算2的以st0為冪的指數(shù),并減去1.0,st0的值的范圍必須在-1.0和+1.0之間。所有這些指令保存結(jié)果到st0并且沒 有操作數(shù)。

fsincos計(jì)算st0值的sin和cos,保存sin結(jié)果到st0,壓入cos值到FPU寄存器堆棧。fptan計(jì)算st0的tag值,保存結(jié) 果到st0,并壓入值1.0堆棧。fpatan計(jì)算st1的arctag,并和st0相除,保存結(jié)果到st1并彈出寄存器堆棧。fyl2x計(jì)算st0的二 進(jìn)制算術(shù)結(jié)果,乘以st1值,保存結(jié)果到st1,然后彈出FPU寄存器堆棧。fyl2xp1執(zhí)行相同操作,但它在計(jì)算對(duì)數(shù)前和1.0相加,保存結(jié)果到 st0。fprem計(jì)算st0和st1相除的余數(shù)到st1,結(jié)果到st0。fprem1執(zhí)行和fprem相同的操作,但它計(jì)算IEEE標(biāo)志754指定的余 數(shù)。fscale截去st1的值并和st0值相加。fxtract分隔st0值為指數(shù)和有效數(shù)字,保存指數(shù)到st0,壓入有效數(shù)字到寄存器堆棧。fnop 不執(zhí)行任何操作。這些指令沒有操作數(shù)。

fxch交換st0和另一個(gè)FPU寄存器的內(nèi)容。這個(gè)操作數(shù)必須為FPU寄存器,不用指定操作數(shù),st0和st1內(nèi)容將被交換。

fcom和fcomp比較st0和源操作數(shù),并格局結(jié)構(gòu)設(shè)置FPU狀態(tài)字標(biāo)志。fcomp執(zhí)行操作后還將彈出寄存器堆棧。操作數(shù)可以為內(nèi)存中單精度或雙精度浮點(diǎn)或FPU寄存器。當(dāng)沒有指定源操作數(shù)時(shí)將使用st1.

ficom word [bx]       ; 16位整數(shù)和st0比較

fcomi,fcomip,fucomi,fucomip用st0和另一個(gè)FPU寄存器比較并根據(jù)結(jié)果設(shè)置標(biāo)志ZF,PF和CF。fcomip和 fucomip還將在執(zhí)行操作后彈出寄存器堆棧。fcmov助記符后面跟著表2.2列出的FPU條件助記符組成的指令如果給定測(cè)試條件為true時(shí)傳送指 定FPU寄存器到st0寄存器。這些指令有兩種不同語法,一種是跟著指定源FPU寄存器的單一操作數(shù),另一種帶有兩個(gè)操作數(shù),此時(shí)目的操作數(shù)為st0,第 二個(gè)操作數(shù)為源FPU寄存器。

fcomi st2             ; 比較st0和st2并設(shè)置標(biāo)志
fcmovb st0,st2        ; 如果小于傳送st2到st0
助記符 測(cè)試條件 描述
b CF=1 小于
e ZF=1 等于
be CF或ZF=1 不大于
u PF=1 無序的
nb CF=0 不小于
ne ZF=0 不相等
nbe CF且ZF=0 大于
nu PF=0 有序的
表2.2:FPU條件

ftst比較st0和0.0并根據(jù)結(jié)果設(shè)置FPU狀態(tài)字標(biāo)志。fxam檢查st0內(nèi)容并設(shè)置FPU狀態(tài)字來標(biāo)識(shí)該寄存器值類型。這些指令沒有操作數(shù)。

fstsw和fnstsw保存當(dāng)前FPU狀態(tài)字到目的位置。目的操作數(shù)可以為16位內(nèi)容或ax寄存器。fstsw在保持狀態(tài)字前檢查未知的沒有屏蔽的FPU異常,而fnstsw不這么做。

fstcw和fnstcw保存當(dāng)前FPU狀態(tài)字到指定的內(nèi)存中目的地址。fstcw在保持狀態(tài)字前檢查未知沒有屏蔽的FPU異常,而fnstcw不這樣。fldcw載入操作數(shù)到FPU控制字。操作數(shù)必須為16位內(nèi)存地址。

fstenv和fnstenv保存當(dāng)前FPU操作環(huán)境到目的操作數(shù)指定的內(nèi)存地址,然后屏蔽所有FPU異常。fstenv在處理前檢查待處理的未屏 蔽的FPU異常,fnstenv將不檢查。flden從內(nèi)存中載入完整的操作環(huán)境到FPU。fsave和fnsave保存當(dāng)前FPU狀態(tài)(操作環(huán)境和寄存 器堆棧)到內(nèi)存中定制的目的地址并重新初始化FPU。fsave在處理前檢查待處理的非屏蔽FPU異常,fnsave不檢查。frstor從指定內(nèi)存位置 載入FPU狀態(tài)。所有這些指令都需要一個(gè)內(nèi)存位置操作數(shù)。

finit和fninit設(shè)置FPU操作環(huán)境到默認(rèn)狀態(tài)。finit在處理前檢查待處理非屏蔽FPU異常,而fninit不檢查。fclex和 fnclex清除FPU狀態(tài)字中FPU異常標(biāo)志。fclex在處理前檢查待處理非屏蔽FPU異常,fnclex不檢查。wait和fwait為相同指令, 將導(dǎo)致處理器檢查待處理的非屏蔽FPU異常并在處理前處理它們。這些指令沒有操作數(shù)。

ffree設(shè)置和指定FPU寄存器相關(guān)的tag為0。操作數(shù)必須為一個(gè)FPU寄存器。

fincstp和fdecstp翻轉(zhuǎn)FPU堆棧為1或棧頂指針減1.這些指令沒有操作數(shù)。

2.1.14 MMX 指令

MMX指令 操作壓縮整數(shù)或MMX寄存器,MMX寄存器為80位FPU寄存器的低64位。因?yàn)榇薓MX指令不能和FPU指令一起使用。他們可以操作壓縮字節(jié)(八個(gè)8位 整數(shù)),壓縮字(四個(gè)16位整數(shù))或壓縮雙字(兩個(gè)32位整數(shù)),使用壓縮格式允許一次對(duì)多個(gè)數(shù)據(jù)執(zhí)行操作。

movq從源操作數(shù)拷貝8字節(jié)到目的操作數(shù)。至少一個(gè)操作數(shù)必須為MMX寄存器,第二個(gè)可以為MMX寄存器或64位內(nèi)存地址。

movq mm0,mm1       ; 寄存器到寄存器移動(dòng)8字節(jié)
movq mm2,[ebx]     ; 內(nèi)存到寄存器移動(dòng)8字節(jié)

movd從源操作數(shù)移動(dòng)雙字到目的操作數(shù)。其中一個(gè)操作數(shù)必須為MMX寄存器,第二個(gè)可以為通用寄存器或32位內(nèi)存地址。只使用MMX寄存器的低雙字。

所有通用MMX操作有兩個(gè)操作數(shù),目的操作數(shù)應(yīng)當(dāng)為MMX寄存器,源操作數(shù)可以為MMX寄存器或64位內(nèi)存地址。對(duì)源和目的操作數(shù)執(zhí)行相應(yīng)操作并保 存數(shù)據(jù)單元到目的操作數(shù)。paddb,paddw和paddd計(jì)算壓縮字節(jié),壓縮字,壓縮雙字的和。paddsb,paddsw,psubsb和 psubsw執(zhí)行壓縮字節(jié)或壓縮字的帶符號(hào)saturation的和。paddusb,paddusw,psubusb,psubusw類似,但將計(jì)算無 符號(hào)saturation。pmulhw和pmullw符號(hào)乘壓縮字,保存結(jié)果的高位或低位到目的操作數(shù)。pmaddwd乘壓縮字,加上四個(gè)立即雙字對(duì)來 生成壓縮雙字結(jié)果。pand,por和pxor執(zhí)行qword邏輯操作。pcmpeqb,pcmpeqw和pcmpeqd比較壓縮字節(jié),壓縮字或壓縮雙字 是否相等。如果某對(duì)數(shù)據(jù)元素相等,目的操作數(shù)中相應(yīng)數(shù)據(jù)元素將填充為1,否則填充0.pcmpgtb,pcmpgtw和pcmpgtd執(zhí)行相同操作,但它 們用來檢查是否目的操作數(shù)中數(shù)據(jù)元素大于源操作數(shù)中數(shù)據(jù)元素。packsswb轉(zhuǎn)換帶壓縮符號(hào)字為壓縮帶符號(hào)字節(jié),使用saturation來處理溢出。 packuswb轉(zhuǎn)換壓縮符號(hào)字道壓縮無符號(hào)字節(jié)。源操作數(shù)中轉(zhuǎn)換后的數(shù)據(jù)單元存儲(chǔ)到目的操作數(shù)的低部分,目的操作數(shù)中轉(zhuǎn)換后的數(shù)據(jù)單元存儲(chǔ)到高半部分。 punpckhbw,punpckhwd和punpckhdq從源操作數(shù)和目的操作數(shù)高半部分插入數(shù)據(jù)單元并保持結(jié)果到目的操作數(shù)。 punpcklbw,punpcklwd和punpckldq執(zhí)行相同操作,但它們使用源和目的操作數(shù)的低半部分。

paddsb mm0,[esi]    ; 計(jì)算壓縮字節(jié)符號(hào)saturation和
pcmpeqw mm3,mm7     ; 比較壓縮字是否相當(dāng)

psllw,pslld和psllq對(duì)壓縮字,壓縮雙字或目的操作數(shù)中的一個(gè)qword執(zhí)行邏輯左移,左移位數(shù)由源操作數(shù)指定。 pswlw,psrld和psrlq對(duì)壓縮字,壓縮雙字或目的操作數(shù)中的一個(gè)qword執(zhí)行邏輯右移。psraw和psrad對(duì)壓縮字或雙字執(zhí)行算術(shù)右 移。目的操作數(shù)因?yàn)镸MX寄存器,而源操作數(shù)可以為MMX寄存器,64位內(nèi)存為孩子,或8位立即數(shù)。

psslw mm2,mm4       ; 邏輯左移word
psrad mm4,[ebx]     ; 算術(shù)右移dword

emms是得FPU寄存器可用。如果使用了MMX指令,它必須在使用FPU指令前使用。

2.1.15 SSE 指令

SSE擴(kuò)展增加了更多MMX指令,并且能操作壓縮單精度浮點(diǎn)數(shù)。128位壓縮單浮點(diǎn)格式由4個(gè)單精度浮點(diǎn)數(shù)組成。128位SSE寄存器設(shè)計(jì)用來操作這種數(shù)據(jù)類型。

movapshemovups傳送源操作數(shù)中一個(gè)包含單進(jìn)度值的雙qword操作數(shù)到目的操作數(shù)。至少一個(gè)操作數(shù)必須為SSE寄存器,第二個(gè)操作數(shù) 可以為SSE寄存器或128位內(nèi)存地址。movaps指令的內(nèi)存操作數(shù)必須對(duì)齊在16位字節(jié)邊界,movups指令操作數(shù)不需要對(duì)齊。

movups xmm0,[ebx]   ; 傳送未對(duì)其雙qword

movlps在內(nèi)存和SSE寄存器低qword之間移動(dòng)兩個(gè)壓縮單精度數(shù)據(jù)。movhps在內(nèi)存和SSE寄存器高qword之間移動(dòng)兩個(gè)壓縮單精度數(shù)據(jù)。其中一個(gè)操作數(shù)必須為SSE寄存器,另一個(gè)必須為64位內(nèi)存地址。

movlps xmm0,[ebx]   ; 移動(dòng)內(nèi)存到xmm0低qword
movhps [esi],xmm7   ; 移動(dòng)xmm7高qword到內(nèi)存

movlhps從源寄存器的低qword移動(dòng)壓縮的兩個(gè)浮點(diǎn)數(shù)據(jù)到目的寄存器。movhlps從源寄存器高qword移動(dòng)兩個(gè)壓縮單浮點(diǎn)數(shù)到目的寄存器的低qword。這兩個(gè)操作數(shù)都必須為SSE寄存器。

movmskps傳送SSE寄存器中4個(gè)單浮點(diǎn)數(shù)據(jù)的最高位到一個(gè)通用寄存器的低4位。源操作數(shù)必須為SSE寄存器,目的操作數(shù)必須為通用寄存器。

movss在源和目的操作數(shù)(只傳送低dword)傳送單浮點(diǎn)數(shù)據(jù)。至少一個(gè)操作數(shù)必須為SSE寄存器,第二個(gè)操作數(shù)可以為SSE寄存器或32位內(nèi)存地址。

movss [edi],xmm3    ; 移動(dòng)xmm3低dword到內(nèi)存

每一個(gè)SSE算術(shù)操作都有兩種。當(dāng)助記符以ps結(jié)尾時(shí),源操作數(shù)可以為128位內(nèi)存地址或SSE寄存器,目的操作數(shù)必須為SSE寄存器,操作壓縮的 四個(gè)浮點(diǎn)數(shù)據(jù),對(duì)于對(duì)應(yīng)數(shù)據(jù)元素對(duì),結(jié)果保存在目的寄存器。當(dāng)助記符以ss結(jié)尾時(shí),源操作數(shù)可以為32位內(nèi)存地址或SSE寄存器,目的操作數(shù)必須為SSE 寄存器,操作于單浮點(diǎn)數(shù)據(jù),此時(shí)只適用SSE寄存器的低dword。addps和addss計(jì)算和,mulps和mulss計(jì)算積,divps和 divss計(jì)算目的值和源值的商,rcpps和rcpss計(jì)算源操作數(shù)的近似倒數(shù),sqrtps和sqrtss計(jì)算源操作數(shù)的開放,rsqrtps和 rsqrtss計(jì)算源值的開方的近似倒數(shù),maxps和maxss比較源和目的值并返回大的值,minps和minss計(jì)算源和目的值并返回小的值。

mulss xmm0,[ebx]    ; 乘以單浮點(diǎn)數(shù)據(jù)
addps xmm3,xmm7     ; 加上壓縮單浮點(diǎn)數(shù)據(jù)

andps,andnps,orps和xorps對(duì)壓縮單精度數(shù)據(jù)執(zhí)行邏輯操作。源操作數(shù)可以為128位內(nèi)存地址或SSE寄存器,目的操作數(shù)必須為SSE寄存器。

cmpps比較壓縮單精度數(shù)并返回結(jié)果掩碼到目的操作數(shù),目的操作數(shù)只能為SSE寄存器。源操作數(shù)可以為128位誒從地址或SSE寄存器,第三個(gè)參 數(shù)必須為表2.3中列出的8個(gè)比較條件操作數(shù)立即數(shù)。cmpss對(duì)單浮點(diǎn)數(shù)據(jù)執(zhí)行相同的操作,但它只影響目的寄存器的低dowrd,此時(shí)源操作數(shù)可以為 32位內(nèi)存地址或SSE寄存器。這兩個(gè)指令也包含只有兩個(gè)操作數(shù)和條件編碼的助記符。這些助記符有cmp助記符后跟著表2.3列出的助記符,以及ps或 ss構(gòu)成。

cmpps xmm2,xmm4,0   ; 比較壓縮單精度值
cmpltss xmm0,[ebx]  ; 比較單精度數(shù)據(jù)

comiss和ucomiss比較單精度并設(shè)置標(biāo)志ZF,PF和CF來表示結(jié)果。目的操作數(shù)必須為SSE寄存器,源操作數(shù)可以為32位內(nèi)存地址或SSE寄存器。

代碼 助記符 描述
0 eq 相等
1 lt 小于
2 le 小于后等于
3 unord 無序
4 neq 不等
5 nlt 不小于
6 nle 不小于不等于
7 ord 有序

shufps從目的操作數(shù)移動(dòng)任何兩個(gè)四單精度數(shù)據(jù)到目的操作數(shù)的低qword,源操作數(shù)中4個(gè)值的任何兩個(gè)到目的操作數(shù)的高qword。目的操作 數(shù)必須為SSE寄存器,源操作數(shù)可以為128位內(nèi)存地址或SSE寄存器,第三個(gè)操作數(shù)必須8位立即數(shù)來指定選擇移動(dòng)那些數(shù)據(jù)到目的操作數(shù)。位0和1選擇移 動(dòng)目的操作數(shù)到結(jié)果的低dword,位2和3移動(dòng)目的操作數(shù)到第二個(gè)dword,位4和5移動(dòng)源操作數(shù)的到結(jié)果的第三個(gè)dword,位6和7移動(dòng)源操作數(shù) 到結(jié)果的高dword。

shufps xmm0,xmm0,10010011b ; 攪亂dword

unpckhps執(zhí)行從源和目的操作數(shù)高部分插入的未壓縮數(shù)據(jù),并保存結(jié)果到目的操作數(shù)。源操作數(shù)可以為128位內(nèi)存地址或SSE寄存器。unpcklps執(zhí)行從源和目的操作數(shù)低部分插入的未壓縮數(shù)據(jù),并保持結(jié)果到目的操作數(shù),操作數(shù)規(guī)則相同。

cvtpi2ps轉(zhuǎn)換壓縮的2dword整數(shù)到壓縮的2單浮點(diǎn)數(shù)據(jù),并保存結(jié)果到目的操作數(shù)的低qword,目的操作數(shù)應(yīng)為SSE寄存器。源操作數(shù)可以為64位內(nèi)存地址或MMX寄存器。

cvtpi2ps xmm0,mm0          ; 整合為單精度數(shù)

cvtsi2ss轉(zhuǎn)換dword整數(shù)位單精度浮點(diǎn)數(shù)并保存結(jié)果到目的操作數(shù)的低dword,目的操作數(shù)必須為SSE寄存器。源操作數(shù)可以為32位內(nèi)存地址或32位通用寄存器。

ctsi2ss xmm0,eax           ; 整合為但精度數(shù)

cvtps2pi轉(zhuǎn)換2單精度浮點(diǎn)數(shù)為壓縮2dword整數(shù)并保存結(jié)果到目的操作數(shù),目的操作數(shù)必須為通用寄存器。源操作數(shù)可以為64位內(nèi)存地址或SSE寄存器,只適用SSE寄存器的低qword。cvttps2pi操作結(jié)果類似,除了截去近似為整數(shù),操作數(shù)規(guī)則相同。

cvtps2pi mm0,xmm0          ; 單精度數(shù)到整數(shù)

cvtss2si轉(zhuǎn)換2單精度浮點(diǎn)數(shù)為壓縮2dword整數(shù)并保存結(jié)果到目的操作數(shù),目的操作數(shù)必須為32位通用寄存器。源操作數(shù)可以為32位內(nèi)存 地址或SSE寄存器,只適用SSE寄存器的低qword。cvttss2pi操作結(jié)果類似,除了截去近似為整數(shù),操作數(shù)規(guī)則相同。

cvtss2pi eax,xmm0          ; 單精度數(shù)到整數(shù)

pextrw拷貝第三個(gè)操作數(shù)指定的源操作數(shù)word到目的操作數(shù)。源操作數(shù)必須為MMX寄存器,目的操作數(shù)必須為32位通用寄存器(僅影響低word),第三個(gè)操作數(shù)必須為8位立即數(shù)。

pextrw eax,mm0,1           ; 取word到eax

pinsrw插入第三個(gè)操作數(shù)指定的word到目的操作數(shù)中第三個(gè)操作數(shù)指定的位置,第三個(gè)操作數(shù)必須為8位立即數(shù)。目的操作數(shù)必須為MMX寄存器,源操作數(shù)可以為16位內(nèi)存地址或32位通用寄存器(只適用寄存器的低word)。

pinsrw mm1,ebx,2           ; 從ebx插入word

pavgb和pavgw計(jì)算壓縮字節(jié)或字平均值。pmaxub返回壓縮無符號(hào)字節(jié)的最大值,pminub返回壓縮無符號(hào)字節(jié)的最小值,pmaxsw 返回壓縮無符號(hào)字的最大值,pminsw返回壓縮無符號(hào)字的最小值。pmulhuw執(zhí)行無符號(hào)壓縮字乘法并保存結(jié)果到目的操作數(shù)的高word。 psadbw計(jì)算壓縮無符號(hào)字節(jié)絕對(duì)差別,匯總不同點(diǎn),并保存匯總到目的操作數(shù)的低word。所有這些指令操作數(shù)規(guī)則和上一節(jié)講述的MMX操作相同。

pmovmskb創(chuàng)建源操作數(shù)每一個(gè)字節(jié)的自高位掩碼,并保存結(jié)果到目的操作數(shù)的低byte。源操作數(shù)必須為MMX寄存器,目的操作數(shù)必須為32位通用寄存器。

pshufw插入word源操作數(shù)到目的操作數(shù)中第三個(gè)操作數(shù)指定的位置。目的操作數(shù)必須為MMX寄存器,源操作數(shù)可以為64位內(nèi)存地址或MMX寄存器,第三個(gè)操作數(shù)必須8位立即數(shù)用來選擇那些值將移動(dòng)到目的操作數(shù),和shufps指令第三個(gè)操作數(shù)相同方式。

ovntq使用非臨時(shí)緩沖提示以最小緩沖損失方式從源操作數(shù)移動(dòng)qword到內(nèi)存。源操作數(shù)必須為MX寄存器,目的寄存器應(yīng)為64位內(nèi)存地址。 movntps使用非臨時(shí)提示從SSE寄存器保存壓縮單精度數(shù)據(jù)到內(nèi)存。源操作數(shù)必須為SSE寄存器,目的操作數(shù)必須為128位內(nèi)存地址。 maskmovq使用非臨時(shí)提示方式保存第一個(gè)操作數(shù)指定的字節(jié)到64位內(nèi)存地址。兩個(gè)操作數(shù)都必須為MMX寄存器,第二個(gè)操作數(shù)決定源操作數(shù)中那些字節(jié) 將寫到內(nèi)存中。內(nèi)存地址由DS段中DI(或EDI)寄存器指向。

prefetcht0,prefetcht1,prefetcht2和prefetchnta獲取操作數(shù)指定的字節(jié)所處內(nèi)存數(shù)據(jù)行到指定位置。操作數(shù)應(yīng)為8位內(nèi)存地址。

sfence同步所有在它之前所有創(chuàng)建指令操作。這條指令沒有操作數(shù)。

ldmxcsr載入32位內(nèi)存操作數(shù)到MXCSR寄存器。stmxcsr保存MXCSR內(nèi)容到32位寄存器。

fxsave保存FPU,MXCSR寄存器當(dāng)前狀態(tài),和所有FPU和SSE寄存器內(nèi)容到512字節(jié)目的操作數(shù)指定的內(nèi)存地址。fxrstor重新載 入前面用fxsave指令保存的512字節(jié)內(nèi)存地址。這兩條指令內(nèi)存操作數(shù)必須對(duì)齊在16字節(jié)邊界上,它不能聲明任何指定大小操作數(shù)。

2.1.16 SSE2指令

SSE2擴(kuò)展用來操作壓縮雙精度浮點(diǎn)數(shù)據(jù),擴(kuò)展MMX指令語法,并且增加了新的指令。

movapd和movupd從源操作數(shù)傳送包含壓縮雙精度數(shù)據(jù)的雙qword操作數(shù)到目的操作數(shù)。這些指令類似movaps和movups,操作數(shù)規(guī)則也相同。

movmskpd傳送SSE寄存器兩個(gè)雙精度數(shù)最高位到通用寄存器低兩位。這條指令和movmskps類似并有相同操作數(shù)規(guī)則。

movsd在源和目的操作數(shù)之間傳送雙精度數(shù)(值傳送低qword)。其中至少一個(gè)操作數(shù)為SSE寄存器,第二個(gè)可以為SSE寄存器或64位內(nèi)存地址。

雙精度值算術(shù)操作 有:addpd,addsd,subpd,subsd,mulpd,mulsd,divpd,divsd,sqrtpd,sqrtsd,maxpd,maxsd,minpd,minsd, 它們和上一節(jié)講述的單浮點(diǎn)算術(shù)操作類似。當(dāng)助記符以pd而不是ps結(jié)尾時(shí),操作針對(duì)于壓縮的2雙精度數(shù),但操作數(shù)規(guī)則相同。當(dāng)助記符以sd而不是ss結(jié)尾 時(shí),源操作數(shù)可以為64位內(nèi)存地址或SSE寄存器,目的寄存器必須為SSE寄存器并且操作于雙精度數(shù),此時(shí)只適用SSE寄存器的低qword。

andpd,andnpd,orpd和xorpd對(duì)壓縮雙精度值執(zhí)行邏輯操作。它們和針對(duì)單精度的邏輯操作類似并且有相同的操作數(shù)規(guī)則。

cmppd比較壓縮雙精度數(shù)并返回掩碼結(jié)果到目的操作數(shù)。這條指令和cmpps類似,并且有相同的操作數(shù)規(guī)則。cmpsd對(duì)雙精度數(shù)據(jù)執(zhí)行相同操作,但它只影響目的寄存器的低qword。接受兩個(gè)操作數(shù)的指令由cmp助記符,表2.3列出的條件助記符和pd或sd組成。

comisd和ucomisd比較雙精度操作數(shù)并設(shè)置標(biāo)志ZF,PF和CF來表示結(jié)果。目的操作數(shù)必須為SSE寄存器,源操作數(shù)可以為128位內(nèi)存地址或SSE寄存器。

shufpd從目的操作數(shù)移動(dòng)任何兩個(gè)雙精度數(shù)到目的操作數(shù)的低qword,源操作數(shù)任何兩個(gè)值值到目的寄存器的高qword。這條指令和 shufps類似并且有相同的操作數(shù)規(guī)則。第三個(gè)操作數(shù)位0指定將移動(dòng)到目的操作數(shù)的值,位1選擇將從源操作數(shù)移動(dòng)的值,其他位為保留的必須為0。

unpckhpd在源和目的操作數(shù)之間執(zhí)行壓縮高qword,unpcklpd在源和目的操作數(shù)之間執(zhí)行未壓縮低qword。它們是unpckhps和unpcklps類似,并且有相同的操作數(shù)規(guī)則。

cvtps2pd轉(zhuǎn)換壓縮2單精度浮點(diǎn)數(shù)據(jù)為兩個(gè)壓縮的雙精度浮點(diǎn)數(shù)據(jù),目的操作數(shù)必須為SSE寄存器,源操作數(shù)可以為64位內(nèi)存地址或SSE寄存 器。 cvtpd2ps轉(zhuǎn)換壓縮2擴(kuò)展雙精度浮點(diǎn)數(shù)據(jù)為壓縮2單精度浮點(diǎn)數(shù)據(jù),目的操作數(shù)必須為SSE寄存器,源操作數(shù)可以為128位內(nèi)存地址或SSE寄存器。 cvtss2sd轉(zhuǎn)換單精度浮點(diǎn)數(shù)據(jù)為雙精度浮點(diǎn)數(shù)據(jù),目的操作數(shù)必須為SSE寄存器,源操作數(shù)可以為32位內(nèi)存地址或SSE寄存器。cvtsd2ss轉(zhuǎn) 換擴(kuò)展雙精度數(shù)據(jù)為單精度浮點(diǎn)數(shù)據(jù),目的操作數(shù)必須為SSE寄存器,源操作數(shù)可以為64位內(nèi)存地址或SSE寄存器。

cvtpi2pd轉(zhuǎn)換壓縮2 dword整數(shù)位壓縮雙精度浮點(diǎn)數(shù)據(jù),目的操作數(shù)必須為SSE寄存器,源操作數(shù)可以為64位內(nèi)存地址或MMX寄存器。cvtsi2sd轉(zhuǎn)換一個(gè)dword 整數(shù)為雙精度浮點(diǎn)數(shù)據(jù),目的操作數(shù)必須為SSE寄存器,源操作數(shù)可以為32位內(nèi)存地址或32位通用寄存器。cvtpd2pi轉(zhuǎn)換壓縮雙精度浮點(diǎn)數(shù)據(jù)為壓縮 2 dword整數(shù),目的操作數(shù)應(yīng)為MMX寄存器,源操作數(shù)可以為128位內(nèi)存地址或SSE寄存器。cvttpd2pi執(zhí)行類似操作,除了它將源值截?cái)嗟秸? 數(shù),操作數(shù)規(guī)則也一樣。cvtsd2si轉(zhuǎn)換雙精度浮點(diǎn)數(shù)據(jù)為dword整數(shù),目的操作數(shù)應(yīng)為32位通用寄存器,源操作數(shù)可以為64為內(nèi)存地址或SSE寄 存器。cvttsd2si執(zhí)行相同吃哦啊在,除了將源值截為整數(shù),操作數(shù)規(guī)則也一樣。

cvtps2dq和cvttps2dq轉(zhuǎn)換壓縮單精度浮點(diǎn)數(shù)據(jù)為壓縮4 dword整數(shù),保存它們的值到目的操作數(shù)。cvtpd2dq和cvttpd2dq轉(zhuǎn)換壓縮雙精度浮點(diǎn)數(shù)據(jù)為壓縮2 dword整數(shù),保存結(jié)果到目的操作數(shù)的低qword。cvtdq2ps轉(zhuǎn)換壓縮4dword幀數(shù)為壓縮單精度浮點(diǎn)數(shù)據(jù)。cvtdq2pd從源操作數(shù)低 qword轉(zhuǎn)換壓縮2 dword整數(shù)為壓縮雙精度浮點(diǎn)數(shù)據(jù)。所有這些指令目的操作數(shù)必須為SSE寄存器,源操作數(shù)可以為128位內(nèi)存地址或SSE寄存器。

movdqa和movdqu傳送源操作數(shù)中雙qword大小的壓縮整數(shù)為目的操作數(shù)。至少其中一個(gè)操作數(shù)必須為SSE寄存器,第二個(gè)可以為SSE寄存器或128位內(nèi)存地址。movdqa指令內(nèi)存操作數(shù)必須16字節(jié)對(duì)齊,movdqu指令操作數(shù)不需要對(duì)齊。

movq2dq移動(dòng)MMX源寄存器內(nèi)容到目的SSE寄存器低qword。movdq2q傳送源SSE寄存器低qword到目的MMX寄存器。

movq2dq xmm0,mm1     ; MMX寄存器傳送到SSE寄存器
movdq2q mm0,xmm1     ; SSE寄存器傳送到MMX寄存器

所有MMX指令操作的64位壓縮整數(shù)(用p開頭的助記符)擴(kuò)展能操作SSE寄存器中128位壓縮整數(shù)。left to do。pshufw指令另外,它不需要擴(kuò)展語法,但有兩種新的變種:pshufhw和pshuflw,他們只允許擴(kuò)展語法,并且分別針對(duì)操作數(shù)高或低 qword執(zhí)行和pshufw相同操作。此外pshufd為新增指令,用來執(zhí)行和pshufw相同的操作,但它操作dword而不是word,它只允許擴(kuò) 展語法。

psubb xmm0,[esi]     ; 減16壓縮字節(jié)
pextrw eax,xmm0,7    ; 提取最高word到eax

paddq執(zhí)行兩個(gè)壓縮qword的和,psubq執(zhí)行兩個(gè)壓縮qword的差,puludq執(zhí)行無符號(hào)乘法每一個(gè)對(duì)應(yīng)qword的低dword,并返回結(jié)果到壓縮qword。這些指令和2.1.14講述的通用MMX操作有相同規(guī)則。

pslldq和psrldq執(zhí)行邏輯左或右移雙dqword目的操作數(shù),移動(dòng)位數(shù)由源操作數(shù)指定。目的操作數(shù)必須為SSE寄存器,源操作數(shù)應(yīng)為8位立即數(shù)。

punpckhqdq源操作數(shù)高qword和目的操作數(shù)高qword,并將結(jié)果寫到目的SSE寄存器中。punpcklqdq插入源操作數(shù)低qword和目的操作數(shù)低qword,并將結(jié)果寫到目的SSE寄存器中。源操作數(shù)可以為128位內(nèi)存地址或SSE寄存器。

movntdq使用非臨時(shí)提示從SSE寄存器保存壓縮整數(shù)數(shù)據(jù)到內(nèi)存。源操作數(shù)應(yīng)為SSE寄存器,目的操作數(shù)應(yīng)為128位內(nèi)存地址。movntpd 使用非臨時(shí)提示從SSE寄存器保存壓縮雙精度數(shù)據(jù)到內(nèi)存。源操作數(shù)應(yīng)為32位通用寄存器,目的操作數(shù)應(yīng)為32位內(nèi)存地址。maskmovdqu使用非臨時(shí) 提示從第一個(gè)參數(shù)保存選擇位到128位內(nèi)存地址。這兩條指令操作數(shù)都應(yīng)為SSE寄存器,第二個(gè)操作數(shù)選擇了那些字節(jié)將從源操作數(shù)寫到目的操作數(shù)。內(nèi)存地址 有DS段中DI(或EDI)寄存器指定,不需要對(duì)齊。

clflush寫并且無效指定操作數(shù)地址字節(jié)的緩沖行,指定操作數(shù)必須為8位內(nèi)存位置。

lfence執(zhí)行載入同步。mfence執(zhí)行訪問同步。所以它組合了sfence(上一節(jié)講述的)和lfence指令功能。這些指令沒有任何操作數(shù)。

2.1.17 SSE3指令

Prescott技術(shù)發(fā)明了新的指令來提高SSE和SSE2性能 - 稱為SSE3。

fisttp行為和fistp指令相似,并且允許相同操作數(shù),唯一區(qū)別是它總是會(huì)截操作,無論當(dāng)前的舍入模式。

movshdup載入目的操作數(shù)為原值同樣尺寸用兩個(gè)重復(fù)的高dword填充每一個(gè)qword的128位值。movsldup執(zhí)行相同動(dòng)作,除了它拷貝低dword。目的操作數(shù)應(yīng)為SSE寄存器,源操作數(shù)可以為SSE寄存器或128位內(nèi)存地址。

movddup載入64為源值,賦值它到目的操作數(shù)的高和低qword。目的操作數(shù)應(yīng)當(dāng)為SSE寄存器,源操作數(shù)可以為SSE寄存器或64位內(nèi)存地址。

lddqu是和movdqu執(zhí)行等價(jià)功能的指令,但能在源操作數(shù)跨緩沖行邊界時(shí)提高性能。目的操作數(shù)必須為SSE寄存器,源操作數(shù)必須為128位內(nèi)存地址。

addsubps執(zhí)行第二和第四組單精度和,第一和第三組單精度差。addsupd執(zhí)行第二組雙精度和,第一組雙精度差。haddps執(zhí)行源和目的 操作數(shù)每個(gè)qword的兩個(gè)單精度和,保存結(jié)果到目的操作數(shù)低qword,源操作數(shù)結(jié)果到目的操作數(shù)高qword。haddpd對(duì)每個(gè)操作數(shù)執(zhí)行兩個(gè)雙精 度值和,并保存目的操作數(shù)中結(jié)果到目的操作數(shù)的低qword,源操作數(shù)結(jié)果到目的操作數(shù)高qword。所有這些指令都需要SSE寄存器為目的操作數(shù),源操 作數(shù)可以為SSE寄存器或128位內(nèi)存地址。

monitor創(chuàng)建回寫地址行監(jiān)視。它需要三個(gè)有順序的操作數(shù)EAX,ECX和EDX。mwait等待回寫到monitor創(chuàng)建的地址區(qū)域。它使用帶有額外參數(shù)的兩個(gè)操作數(shù),第一個(gè)為EAX,第二個(gè)為EDX。

2.1.18 AMD 3DNOW!指令

3DNow!擴(kuò)展增加新的2.1.14列出MMX指令,并且能操作64位壓縮浮點(diǎn)數(shù)據(jù),每一個(gè)有兩個(gè)單精度浮點(diǎn)數(shù)據(jù)組成。

這些指令規(guī)則和通用MMX操作相同,目的操作數(shù)必須為MMX寄存器,源操作數(shù)可以為MMX寄存器或64位內(nèi)存地址。pawgusb計(jì)算壓縮無符號(hào)字 節(jié)平均值。pmulhrw執(zhí)行帶符號(hào)壓縮字的乘積,舍入每一個(gè)dword結(jié)果高半部分到目的操作數(shù)。pi2fd轉(zhuǎn)換壓縮dword整數(shù)為壓縮浮點(diǎn)數(shù)。 pf2id使用舍入轉(zhuǎn)換壓縮浮點(diǎn)數(shù)據(jù)為壓縮dword整數(shù)。pi2fw轉(zhuǎn)換壓縮字整數(shù)到壓縮浮點(diǎn)數(shù),只是喲個(gè)源操作數(shù)中每個(gè)dword的低word。 pf2iw轉(zhuǎn)換壓縮浮點(diǎn)數(shù)據(jù)為壓縮word整數(shù),結(jié)果使用符號(hào)擴(kuò)展擴(kuò)展為壓縮浮點(diǎn)數(shù)。pfadd計(jì)算壓縮浮點(diǎn)數(shù)的和。pfsub和pfsubr計(jì)算壓縮浮 點(diǎn)數(shù)的差,第一個(gè)用目的值減去源值,第二個(gè)用源值減去目的值。pfmul計(jì)算壓縮浮點(diǎn)數(shù)的積。pfacc計(jì)算目的操作數(shù)地和高浮點(diǎn)數(shù)的和,保存結(jié)果到目的 操作數(shù)的低dword,并且計(jì)算源操作數(shù)的低和高dword的和,保存結(jié)果到目的寄存器的高dword。pfnacc用目的操作數(shù)的高浮點(diǎn)數(shù)減去低浮點(diǎn) 數(shù),保存結(jié)果到目的操作數(shù)的低dword,并結(jié)算源操作數(shù)的高和低dword的差,保存結(jié)果到目的操作數(shù)的高dword。pfpnacc用目的操作數(shù)的高 浮點(diǎn)數(shù)據(jù)減去低浮點(diǎn)數(shù)據(jù),保存結(jié)果到目的操作數(shù)的低dword,并計(jì)算源操作數(shù)低和高浮點(diǎn)數(shù)的和,保存結(jié)果到目的操作數(shù)的高dword。pfmax和 pfmin計(jì)算浮點(diǎn)數(shù)的最大和最小值。pswapd翻轉(zhuǎn)源操作數(shù)的高低dword。pfrcp返回原操作數(shù)的近似浮點(diǎn)值倒數(shù)。pfrsqrt返回原操作數(shù) 的開方的近似倒數(shù)。pfrcpit1執(zhí)行第一步Newton-Raphson迭代開方。pfrcpit2計(jì)算第二步Newton-Raphson迭代開 發(fā)。pfcmpeq,pfcmpge和pfcmpgt比較壓縮浮點(diǎn)數(shù)并根據(jù)比較結(jié)果設(shè)置目的操作數(shù)中相應(yīng)數(shù)據(jù)元素的位(全部置為1或置為0),第一個(gè)檢查 值是否相等,第二個(gè)檢查目的值是否大于或等于源之,第三個(gè)檢查是否目的值大于源值。

prefetch和prefetchw從內(nèi)存載入 包含操作數(shù)指定字節(jié)的數(shù)據(jù)行,prefetchw指令必須當(dāng)緩沖行中數(shù)據(jù)被修改時(shí)使用,否則應(yīng)使用prefetch指令。操作數(shù)必須為8位內(nèi)存地址。

femms執(zhí)行快速清除MMX狀態(tài)。它沒有操作數(shù)。

2.1.19 x86-64長(zhǎng)模式指令

AMD64和EM64T體系(我們將使用x86-64作為通用名稱)擴(kuò)展x86指令集以用作64位處理。而原始和兼容模式使用相同的寄存器和指令集。新的長(zhǎng)模式擴(kuò)展x86操作64位,并且發(fā)明了一個(gè)新的寄存器。你可以使用use64偽指令來生成這個(gè)模式的代碼。

每一個(gè)通用寄存器都被擴(kuò)展為64位,增加了8個(gè)新的通用寄存器和8個(gè)新的SSE寄存器。表2.4列出了新增的這些寄存器。通用寄存器的小的尺寸為大的值的低部分。你仍然可以在長(zhǎng)模式下訪問ah,bh,ch和dh寄存器,但你不能在新的指令中使用任何新的寄存器。

通常x86體系中任何指令,允許16位或32位操作數(shù)尺寸,在長(zhǎng)模式下還允許64位操作數(shù)。64位操作數(shù)必須在長(zhǎng)模式下尋址,也允許32位尋址,但不能使用基于16位寄存器的地址。下面為長(zhǎng)模式中的mov指令例子:

mov rax,r8           ; 傳送64位通用寄存器
mov al,[rbx]         ; 傳送通過64位寄存器尋址的內(nèi)存
類型 通用寄存器 SSE
8 16 32 64 128
rax
rcx
rdx
rbx
spl rsp
bpl rbp
sil rsi
dil rdi
r8b r8w r8d r8 xmm8
r9b r9w r9d r9 xmm9
r10b r10w r10d r10 xmm10
r11b r11w r11d r11 xmm11
r12b r12w r12d r12 xmm12
r13b r13w r13d r13 xmm13
r14b r14w r14d r14 xmm14
r15b r15w r15d r15 xmm15
表2.4:長(zhǎng)模式新寄存器

長(zhǎng)模式也使用基于地址的指令指針,你可以手動(dòng)用RIP指定,但這些地址也能自動(dòng)由FASM生成,因此在長(zhǎng)模式下沒有64位絕對(duì)地址。你可以通過中括 號(hào)中dword尺寸重寫地址來強(qiáng)制匯編器使用32位絕對(duì)地址。也有一個(gè)使用64位絕對(duì)尋址的例外,它為mov后跟著其中一個(gè)為累加器,第二個(gè)為內(nèi)存操作數(shù) 的情況。使用qword來強(qiáng)制匯編器使用64位絕對(duì)尋址。當(dāng)沒有指定尺寸操作符時(shí),匯編器自動(dòng)生成最佳格式。

mov [qword 0],rax    ; 絕對(duì)64位尋址
mov [dword 0],r15d   ; 絕對(duì)32位尋址
mov [0],rsi          ; 自動(dòng)RIP相對(duì)尋址
mov [rip+3],sil      ; 手動(dòng)RIP相對(duì)尋址

作為64位操作立即數(shù)只可能為32位數(shù),唯一例外是帶有64位通用寄存器目的操作數(shù)的mov指令。試圖其他指令使用64位立即數(shù)將導(dǎo)致錯(cuò)誤。

如果在長(zhǎng)模式下操作32位通用寄存器的指令,64位寄存器的高32位填充為0.這不同于16位或32位那些指令操作,它們保留高位。

新增三條類型轉(zhuǎn)換指令。cdqe符號(hào)擴(kuò)展EAX中dword到qword并保持結(jié)果到RAX。cqo符號(hào)擴(kuò)展RAX qword為雙qword并保存額外位到RDX寄存器。這些指令沒有操作數(shù)。movsxd符號(hào)擴(kuò)展dword源操作數(shù)到64位目的操作數(shù),源操作數(shù)可以為 32為寄存器或內(nèi)存,目的操作數(shù)必須為寄存器。沒有零擴(kuò)展類似指令,因?yàn)樗詣?dòng)由32位寄存器完成,上一段中說明的那樣。movzx和movsx指令遵守 通常規(guī)則,可以使用64位目的操作數(shù),允許擴(kuò)展字節(jié)或字到qword。

所有二進(jìn)制算術(shù)和邏輯指令提升以允許在長(zhǎng)模式下操作64位操作數(shù)。在長(zhǎng)模式下禁止使用十進(jìn)制算術(shù)指令。

堆棧操作,比如push和pop在長(zhǎng)模式下默認(rèn)為64位操作數(shù),不能使用32位操作數(shù)。pusha和popa在長(zhǎng)模式下不可用。

間接near調(diào)整和調(diào)用在長(zhǎng)模式下默認(rèn)為64位操作數(shù),它不能使用32位操作數(shù)。另外,間接far調(diào)整和調(diào)用允許任何x86體系允許的操作數(shù),也允 許使用80位內(nèi)存操作數(shù)(僅EM64T實(shí)現(xiàn)了),80位內(nèi)存操作數(shù)有第一個(gè)定義偏移的8字節(jié)和指定選擇子的最后兩個(gè)字節(jié)組成。長(zhǎng)模式下不允許直接far調(diào) 整和調(diào)用。

I/O指令,in,out,ins和outs為例外指令,它們不允許在長(zhǎng)模式下操作qword操作數(shù)。但其他串操作可以。他們有新的段格式movsq,cmpsq,scasq,lodsq和stosq。RSI和RDI寄存器默認(rèn)用來尋址這些串元素。

lfs,lgs和lss用來擴(kuò)展以接受80位元內(nèi)存操作數(shù)和64位目的寄存器(僅EM64T實(shí)現(xiàn)了)。lds和les不能在長(zhǎng)模式下使用。

系統(tǒng)指令,比如需要48位內(nèi)存操作數(shù)的lgdt,在長(zhǎng)模式下需要80為內(nèi)存操作數(shù)。

cmpxchg16b為64位的cmpxchg8b等價(jià)指令,它使用雙qword內(nèi)存操作數(shù)和64為寄存器來執(zhí)行類似操作。

swapgs為新增指令,它置換GS寄存器和KernelGSbase MSR寄存器的內(nèi)容(MSR地址為0C0000102h)。

syscall和sysret為新增指令,用來在長(zhǎng)模式下提供和sysenter和sysexit相似功能的指令,而sysenter和sysexit在長(zhǎng)模式下不允許使用。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多