日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MMX指令集

發布時間:2023/12/3 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MMX指令集 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這篇來介紹intel cpu的高級特性,SIMD-單指令多數據,從名字來看,就是執行一條指令可以計算多個數據。先從最簡單的mmx指令集來看,在寄存器那篇已經提 到,mmx有 mm0-mm7 共8個64位寄存器,但是寄存器并非獨立寄存器,而是復用了上篇說到的fpu數據堆棧寄存器,也就是說使用mmx指令集會破壞fpu的計算,如果同時使用 著兩種特性,一定要注意這點,避免出現莫名的錯誤。

首先mmx指令集需要cpu的支持,但不是所有cpu都支持,不然也不會稱之為高級特性 了,所以在使用之前需要檢測,檢測指令為cpuid,獲得cpu的特性,cpuid雖然只有一條指令,但是其隱含的內容太多,這里僅僅介紹檢測SIMD指 令集所需要的部分,其他一些信息可參閱Intel 手冊獲得。

當eax為1時,cpuid指令返回cpu簽名信息,放入ecx和edx寄存器中,相應位為1表示支持。檢測SIMD指令集的結果如下:

寄存器位特性
EDX23支持MMX
EDX25支持SSE
EDX26支持SSE2
ECX0支持SSE3

具體檢測代碼如下(AT&T 語法):

.section .datammxstring: .asciz "支持mmx指令集\n"ssestring: .asciz "支持sse指令集\n"sse2string: .asciz "支持sse2指令集\n"sse3string: .asciz "支持sse3指令集\n".section .text .globl _main _main:movl $1, %eaxcpuidmmxop:test $0x800000, %edxjz sseoppushl $mmxstringcall _printfsseop:test $0x2000000, %edxjz sse2oppushl $ssestringcall _printfsse2op:test $0x4000000, %edxjz sse3oppushl $sse2stringcall _printfsse3op:test $0x01, %ecxjz endpushl $sse3stringcall _printf end:pushl $0call _exit

下面正式開始mmx指令集的介紹,使用mmx需要三個步驟:

  • 從整數值創建打包整數,載入mmx寄存器
  • 使用mmx指令集計算
  • 從mmx獲得結果,存入內存

第一個和最后一個步驟比較簡單,僅僅是數據移動而已,這里提到打包,因為這里要單指令多數據,所以需要把多數據合成一個操作數進行計算,存入64位的mmx寄存器中,打包的過程就是把 8個字節/4個字/2個雙字 合成一個64位數據。

從加減法說起,對于普通數據,如果數據溢出可以置標記位,但是對于多數據的運算,由于同時計算多個加法,就不能單純的設置標志,對mmx計算有幾種情況:

環繞運算 截斷其值,丟棄進位 帶符號飽和 最大/最小 帶符號值 無符號飽和 最大/最小 無符號值

其中飽和運算的預設值根據結果的位數決定,有符號8位最大為127,如果超過127,結果按127計算,其他情況與此類似,這里方便與一些圖形處理,比如色彩黑色為0,為無符號最小值,小于其值也按黑色處理。

好 了,到此可以看一下具體的指令,這里的指令有相同的格式,instruction source, destination;其中source可以是mmx寄存器或者64位內存,destination為mmx寄存器。這是AT&T語法,對于 MASM語法源目的操作數相反。

指令說明
paddb環繞打包字節整數加法
paddw環繞打包字整數加法
paddd環繞打包雙字整數加法
paddsb帶符號飽和打包字節整數加法
paddsw帶符號飽和打包字整數加法
paddusb無符號飽和打包字節整數加法
paddusw無符號飽和打包字整數加法
psubb環繞打包字節整數減法
psubw環繞打包字整數減法
psubd環繞打包雙字整數減法
psubsb帶符號飽和打包字節整數減法
psubsw帶符號飽和打包字整數減法
psubusb無符號飽和打包字節整數減法
psubusw無符號飽和打包字整數減法

下面以AT&T加法為例進行說明,這里以飽和方式計算4個無符號字之和:

# add four word # output : result is 18932, 7631, 65535, 510 .section .datavalue1: .short 12300, 2384, 60000, 456value2: .short 6632, 5247, 40000, 54outstring: .asciz "result is %u, %u, %u, %u\n" .section .text .globl _main _main:movq value1, %mm0movq value2, %mm1paddusw %mm1, %mm0movq %mm0, value1movl $value1, %ebxxorl %eax, %eaxmovw 6(%ebx), %axpushl %eaxmovw 4(%ebx), %axpushl %eaxmovw 2(%ebx), %axpushl %eaxmovw (%ebx), %axpushl %eaxpushl $outstringcall _printfpushl $0call _exit

movq 指令把內存中的數據傳送至mmx寄存器,如果數據之前在內存中不是連續的,則需要集中存放,即進行打包,之后使用paddusw進行加法計算,輸出時 word需轉化成dword放入堆棧,可以看到以飽和方式第三個結果為65535,即16位無符號數的最大值。從這里例子可以看出,通過一條指令計算了四 個word整數相加,很大程度上提高了計算的效率,但是同時需要注意,整數的打包以及傳送過程也需要耗時,如果打包操作很多,結果不是提高效率而是降低效 率了。

mmx指令集的加法根據需要有飽和方式和環繞方式計算,但對于乘法而言,由于結果的寬度可能是操作數的兩倍,所以兩種方式看上去都不合適,所以intel提供了兩個指令,一個得到計算結果的低字節,另一個得到計算結果的高字節。

指令描述
pmulluw對無符號16位整數相乘取結果低16位
pmulhuw對無符號16位整數相乘取結果高16位
pmullw對有符號16位整數相乘取結果低16位
pmulhw對有符號16位整數相乘取結果高16位
pmaddwd對4個帶符號整數相乘,高位兩個結果相加存入高32位,低位相同

mmx指令集還提供對四字值進行布爾邏輯操作和移位指令:

指令描述
pand對源和目標操作數按位與操作
pandn對目標操作數進行按位邏輯非操作,然后對源和目標操作數按位與操作
por對源和目標操作數按位或操作
pxor對源和目標操作數按位異或操作
psll對目標操作數執行邏輯左移操作,使用0填充空位
psra對目標操作數執行邏輯右移操作,使用0填充空位

其AT&T指令格式如下:

pand source, destination

其中source是mmx寄存器或者64位內存,destination必須是mmx寄存器。移位指令可以使用字,雙字或者四字操作數,還有移位的位置數量。MASM格式的源目的操作數相反。

mmx構架提供了用于比較兩個值的指令:

指令描述
pcmpeqb比較打包字節整數值的相等性
pcmpeqw比較打包字整數值的相等性
pcmpeqd比較打包雙字整數值的相等性
pcmpgtb判斷打包字節整數值是否大于另一個
pcmpgtw判斷打包字整數值是否大于另一個
pcmpgtd判斷打包雙字整數值是否大于另一個

因為mmx同時比較多個數據,所以不能設置標志,替換的做法是把判斷結果放到目標打包整數值中,如果打包整數值滿足對比提交,就把結果設置為全1,否則設置為全0。

由于mmx指令集并非所有cpu都可以支持,所以對c語言這種編譯通用性的程序而言,是不會貿然使用mmx指令集的,這也對我們手工匯編優化程序提供了很大的空間,但是需要注意打包整數的效率損耗。

另外,intel除了mmx指令集,另有SIMD指令如sse指令集,將會再下篇詳細說明。

轉載:http://fancymore.com/reading/assembler-mmx-instruct.html

轉載于:https://www.cnblogs.com/DeeLMind/p/7367775.html

總結

以上是生活随笔為你收集整理的MMX指令集的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。