複製鏈接
請複製以下鏈接發送給好友

MMX指令

鎖定
MMX指令有8個64位寄存器(MM0~MM7),不過可惜都是借的FPU的, FPU原來有8個80位寄存器(st(0)~st(7)),現在用在了MMX 上,所以用之後要加上一條EMMS指令,用以復位。.
中文名
MMX指令
作    者
HAM
介    紹
有8個64位寄存器
功    能
加上一條EMMS指令,用以復位
基本介紹
MMX寄存器有64位,可以同時進行8對字節或4對字或2對雙字同時相同操作,還可以進行飽和運算,也就是運算結果有個頂點,
不會溢出,當然也可以進行普通運算.
MM表示64位MMX寄存器.
r32表示32位通用寄存器或esi,edi
m32表示32位內存變量
m64表示64位內存變量
m128表示128位內存變量
imm8表示8位立即數
操作數為目的操作數,右操作數為源操作數
'|'字符表示每組數據之間的間隔分隔符
movd MM,r32/m32
把 r32/m32 值賦給 MM 的低32位,高32位清零.
movd r32/m32,MM
把 MM 的低32位值賦給 r32/m32.
例:
當MM0 == 1234567887654321 h,eax == 0abc h時,執行movd MM0,eax,則MM0 == 0abc h
當MM0 == 1234567887654321 h,eax == 0abc h時,執行movd eax,MM0,則eax == 87654321 h
movq MM,MM/m64
把源MM/m64的值送入目的MM.
例:
當MM0 == 1234567887654321 h,MM1 == 3141592653 h時,執行movq MM0,MM1,則MM0 == 3141592653 h
movntq m64,MM
m64 <== MM ,MM內容送入m64,不經過cache.
pmovmskb r32,MM
r[0] <== MM[7]
r[1] <== MM[15]
r[2] <== MM[23]
r[3] <== MM[31]
r[4] <== MM[39]
r[5] <== MM[47]
r[6] <== MM[55]
r[7] <== MM[63]
r[31-8] <== 0
paddsb MM,MM/m64
字節對齊,飽和有符號數(補碼)相加(結果= -128~+127,80h~7fh),值送入目的MM.
當結果小於-128時,結果強制轉為80h,當結果大於+127時,結果強制轉為7fh.
例:
當MM0 == 00 c0 fe 7e 11 h,
MM1 == 12 a6 9c 10 02 h時,執行 paddsb MM0,MM1,
則MM0 == 12 80 9a 7f 13 h
0c0h = -64,0a6h = -90,-64 + (-90) = -154,-154< -128,所以結果為80h
7eh=126,10h=16,126+16=142,142>127,所以結果為7fh
其餘的未飽和所以結果正常.
paddsw MM,MM/m64
按字對齊,飽和有符號數(補碼)相加(結果= -32768~+32767,8000h~7fffh),值送入目的MM.
運算與paddsb類似,當結果小於-32768時,結果強制轉為8000h,當結果大於,+32767時,結果強制轉為7fffh.
paddusb MM,MM/m64
字節對齊,飽和無符號數相加(結果= 0~255,0h~0ffh),值送入目的MM.
當結果大於255時,結果強制轉為0ffh.
例:
當MM0 == 23 11 h,MM1 == fc 22 h時,執行paddusb MM0,MM1,則MM0 == ff 33h
23h = 35,0fch = 253,35 + 253 = 288,288> 255,所以結果為0ffh
paddusw MM,MM/m64
按字對齊,飽和無符號數相加(結果= 0~65535,0h~0ffffh),值送入目的MM.
運算與paddusb類似,當結果大於65535時,結果強制轉為0ffffh.
psubsb MM,MM/m64
字節對齊,飽和有符號數(補碼)相減(結果= -128~+127,80h~7fh),值送入目的MM.
運算與paddsb類似,當結果小於-128時,結果強制轉為80h,當結果大於,+127時,結果強制轉為7fh.
psubsw MM,MM/m64
按字對齊,飽和有符號數(補碼)相減(結果= -32768~+32767,8000h~7fffh),值送入目的MM.
運算與paddsw類似,當結果小於-32768時,結果強制轉為8000h,當結果大於,+32767時,結果強制轉為7fffh.
paddb MM,MM/m64
字節對齊,普通相加,與add指令類似.
例:
當MM0 = 12 34 56 78 ab cd ef feh,
MM1 = 87 69 86 54 3d ea cb 03h,執行paddb MM0,MM1,
則MM0 = 99 9d dc cc e8 b7 ba 01h
paddw MM,MM/m64
按字對齊,普通相加,與add指令類似.
paddd MM,MM/m64
按雙字對齊,普通相加.與add指令類似.
paddq MM,MM/m64
按四字對齊,普通相加.
例:
當MM0 == 0fffffffffffffffeh,MM1 == 3h,執行paddq MM0,MM1,則MM0 = 1h
psubb MM,MM/m64
按字節對齊,普通相減,與sub指令類似.
psubw MM,MM/m64
按字對齊,普通相減,與sub指令類似.
psubd MM,MM/m64
按雙字對齊,普通相減.與add指令類似.
psubq MM,MM/m64
按四字對齊,普通相減.
例:
當MM0 == 1h,MM1 == 3 h,執行psubq MM0,MM1,則MM0 = 0fffffffffffffffeh
psllw MM,MM/m64 psllw MM,imm8
把目的寄存器按字由源存儲器(或imm8 立即數)指定位數邏輯左移,移出的位丟失.
低字移出的位不會移入高字.
例:
當MM0 = 0ffff ffff ffff ffffh,執行psllw MM0,1
則MM0 = 0fffe fffe fffe fffeh
psrlw MM,MM/m64 psrlw MM,imm8
把目的寄存器按字由源存儲器(或imm8 立即數)指定位數邏輯右移,移出的位丟失.
高字移出的位不會移入低字.
例:
當MM0 = 0ffff ffff ffff ffffh,執行psrlw MM0,1
則MM0 = 07fff 7fff 7fff 7fffh
pslld MM,MM/m64 pslld MM,MM imm8
把目的寄存器按雙字由源存儲器(或imm8 立即數)指定位數邏輯左移,移出的位丟失.
低雙字移出的位不會移入高雙字.
例:
當MM0 = 0ffffffff ffffffffh,執行pslld MM0,1
則MM0 = 0fffffffe fffffffeh
psrld MM,MM/m64 psrld MM,imm8
把目的寄存器按雙字由源存儲器(或imm8 立即數)指定位數邏輯右移,移出的位丟失.
高雙字移出的位不會移入低雙字.
例:
當MM0 = 0ffffffff ffffffffh,執行psrld MM0,1
則MM0 = 07fffffff 7fffffffh
pmullw MM,MM/m64
按字對齊,有符號(補碼)相乘,取結果低16位,放入目的寄存器的對應字.
例:
當MM0 == 2 acfeh,MM1 == 9 cef3h,執行 pmulhw,則MM0 = 0000 0000 0012 991ah
2 * 9 = 18,18 = 0000 0012h,取低16位 0012 為結果.
0acfeh == -21250,0cef3h == -12557,-21250*-12557 = 266836250 = 0fe7 991a h,取低16位 991a 為結果.
pmulhw MM,MM/m64
按字對齊,有符號(補碼)相乘,取結果高16位,放入目的寄存器的對應字.
例:
當MM0 == 2 acfeh,MM1 == 9 cef3h,執行 pmulhw,則MM0 = 0000 0000 0000 0fe7h
2 * 9 = 18,18 = 0000 0012h,取高16位 0000 為結果.
0acfeh == -21250,0cef3h == -12557,-21250*-12557 = 266836250 = 0fe7 991a h,取高16位 0fe7 為結果.
▲注:在MMX指令集中沒有除法指令.
﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌
pand MM,MM/m64
64個位'與'操作,結果放入目的寄存器.
pandn MM,MM/m64
目的寄存器按位先取'非',再'與'源寄存器,結果放入目的寄存器.
por MM,MM/m64
64個位'或'操作,結果放入目的寄存器.
pxor MM,MM/m64
64個位'異或'操作,結果放入目的寄存器.
pmaddwd MM,MM/m64
按字對齊有符號(補碼)向量點乘.
高32位 | 低32位
目的寄存器: a0 | a1 | a2 | a3
寄存器: b0 | b1 | b2 | b3
目的寄存器結果: a0*b0+a1*b1 | a2*b2+a3*b3
例:
當MM0 = 0006 8a11 1234 4321h,
MM1 = 0154 c239 ae39 2b35h,當執行pmaddwd MM0,MM1
則MM0 = 1c75a7c1 0583d669h 注意是有符號操作!
pcmpeqb MM,MM/m64
寄存器與目的寄存器字節比較,相等就置目的寄存器對應字節為0ffh,否則為00h
例:
當MM0 == 20 11h,MM1 == 21 11h,執行pcmpeqb MM0,MM1,則MM0 = ff ff ff ff ff ff 00 ff h
注:MM0與MM1的高48為0,因為0 == 0,所以置目的寄存器對應字節為0ffh.
pcmpeqw MM,MM/64
源寄存器與目的寄存器按字比較,相等就置目的寄存器對應字為0ffffh,否則為0000h
pcmpeqd MM,MM/m64
源寄存器與目的寄存器按雙字比較,相等就置目的寄存器對應雙字為0ffffffffh,否則為00000000h
pcmpgtb MM,MM/m64
源寄存器與目的寄存器按字節(有符號補碼)比較,
當目的寄存器對應字節大於源寄存器就置目的寄存器對應字節為0ffh,否則為00h
例:
當MM0 == 80 12 11 h,MM1 == 7f 12 10h,執行pcmpgtb MM0,MM1,則MM0 = 00 00 ffh
因為80h = -128,7fh = 127,-128<127,所以結果為00h
pcmpgtw MM,MM/m64
源寄存器與目的寄存器按字(有符號補碼)比較,
當目的寄存器對應字大於源寄存器就置目的寄存器對應字為0ffffh,否則為0000h
pcmpgtd MM,MM/m64
源寄存器與目的寄存器按雙字(有符號補碼)比較,
當目的寄存器對應雙字大於源寄存器就置目的寄存器對應雙字為0ffffffffh,否則為00000000h
packuswb MM,MM/m64
把目的寄存器按字有符號數壓縮為字節無符號數放入目的寄存器低32位
把源寄存器按字有符號數壓縮為字節無符號數放入目的寄存器高32位
壓縮時負數變為00h,大於255的正數變為0ffh.
高32位 | 低32位
目的寄存器: a0 | a1 | a2 | a3
源寄存器: b0 | b1 | b2 | b3
目的寄存器壓縮結果: b0|b1| b2|b3| a0|a1|a2|a3
例:
當MM0 == 7fff 8000 1234 00ae h,MM1 == 00ad 0123 80ff 0100 h,
執行packuswb MM0,MM1,則MM0 = ad ff 00 ff ff 00 ff ae h.
packsswb MM,MM/m64
把目的寄存器按字有符號數壓縮為字節有符號數放入目的寄存器低32位
把源寄存器按字有符號數壓縮為字節有符號數放入目的寄存器高32位
壓縮時小於-128負數變為80h,大於127的正數變為7fh.
高32位 | 低32位
目的寄存器: a0 | a1 | a2 | a3
源寄存器: b0 | b1 | b2 | b3
目的寄存器壓縮結果: b0|b1| b2|b3| a0|a1|a2|a3
例:
當MM0 == 0fff ff06 0080 0012 h,MM1 == 0001 8000 ffff 7fff h,
執行packsswb MM0,MM1,則MM0 = 01 80 ff 7f 7f 80 7f 12 h
packssdw MM,MM/m64
把目的寄存器按雙字有符號數壓縮為單字有符號數放入目的寄存器低32位
把源寄存器按雙字有符號數壓縮為單字有符號數放入目的寄存器高32位
壓縮時小於-32768負數變為8000h,大於32767的正數變為7fffh.
高32位 | 低32位
目的寄存器:a0 | a1
源寄存器: b0 | b1
目的寄存器壓縮結果: b0 | b1 | a0 | a1
punpcklbw MM,MM/m64
把目的寄存器與源寄存器的低32位按字節交錯排列放入目的寄存器
高32位 | 低32位
目的寄存器: a0|a1|a2|a3|a4|a5|a6|a7
源寄存器: b0|b1|b2|b3|b4|b5|b6|b7
目的寄存器結果:b4|a4|b5|a5|b6|a6|b7|a7
例:
當MM0 == 01 02 03 04 05 06 07 08 h,MM1 == 09 0a 0b 0c 0d 0e 0f 00 h
執行punpcklbw MM0,MM1,則MM0 = 0d 05 0e 06 0f 07 00 08 h
punpcklwd MM,MM/m64
把目的寄存器與源寄存器的低32位按字交錯排列放入目的寄存器
高32位 | 低32位
目的寄存器: a0 | a1 | a2 | a3
源寄存器: b0 | b1 | b2 | b3
目的寄存器結果:b2 | a2 | b3 | a3
punpckldq MM,MM/m64
把目的寄存器與源寄存器的低32位按雙字交錯排列放入目的寄存器
高32位 | 低32位
目的寄存器:a0 | a1
源寄存器: b0 | b1
目的寄存器結果: b1 | a1
punpckhbw MM,MM/m64
把目的寄存器與源寄存器的高32位按字節交錯排列放入目的寄存器
高32位 | 低32位
目的寄存器: a0|a1|a2|a3|a4|a5|a6|a7
源寄存器: b0|b1|b2|b3|b4|b5|b6|b7
目的寄存器結果:b0|a0|b1|a1|b2|a2|b3|a3
例:
當MM0 == 01 02 03 04 05 06 07 08 h,MM1 == 09 0a 0b 0c 0d 0e 0f 00 h
執行punpcklbw MM0,MM1,則MM0 = 09 01 0a 02 0b 03 0c 04 h
punpckhwd MM,MM/m64
把目的寄存器與源寄存器的高32位按字交錯排列放入目的寄存器
高32位 | 低32位
目的寄存器: a0 | a1 | a2 | a3
源寄存器: b0 | b1 | b2 | b3
目的寄存器結果:b0 | a0 | b1 | a1
punpckhdq MM,MM/m64
把目的寄存器與源寄存器的高32位按雙字交錯排列放入目的寄存器
高32位 | 低32位
目的寄存器:a0 | a1
源寄存器: b0 | b1
目的寄存器結果: b0 | a0