首先祝各位親愛的讀者聖誕節快樂喔!這次的主題是組合語言中小數的操作。感覺起來很無聊?沒錯啦,這主題本身連我聽起來連我都覺得有些無聊。但我還是想要把它貼出來,因為呢,藏在主題下面的東西其實有些小故事可以說。也就是,本文的程式碼是講無趣小故事的藉口。
親愛的讀者,如果之前學習過,或者是欣賞過32位元x86組合語言程式的話(附帶一提,那裡的呼叫協定真的是一團糟),可能就知道在該平台上計算小數的主流是x87 fpu指令。x87 fpu指令可以做純量的數學計算,並且配有80-bit浮點數的計算能力。然而,因為x87暫存器設計的關係,個人覺得該指令使用的難度比較高,用起來比較有被綁手的感覺。
而現在,具有x86-64處理器的cpu都具有SSE指令。這套指令裡面就配有小數純量處理的指令,暫存器的使用卻更加的有彈性,用起來也比較開心。於是,在大部份的狀況下,小數的計算利用SSE指令完成,而參數的傳遞,和x64 ABI所說的一樣,也是利用SSE的暫存器(xmm暫存器)來傳遞。
還先不用替x87 fpu掉眼淚。x87指令相對於SSE還是有不可取代的優勢。有些數學函數,像是sin, cos等,如果想要靠硬體來完成,那只能求x87 fpu了。讓x87得以保留飯碗的另一個因素是80-bit浮點數計算能力。總之x87在這幾年應該不會失業,請各位放心 ^_^
剩下的呢,請各位親愛的讀者欣賞一下簡單的程式小品囉。
.section .text .global main .type main, %function main: /*堆疊指標向16位元組對齊*/ sub $8, %rsp /*計算圓面積*/ movsd .Lr, %xmm0 movsd %xmm0, %xmm2 movsd .Lpi, %xmm1 mulsd %xmm0, %xmm0 mulsd %xmm1, %xmm0 mov $.Lfmt, %rdi /*rax表示會使用到的xmm暫存器數量*/ mov $2, %rax /*浮點參數依照xmm0, xmm1 ..的順序傳遞*/ movsd %xmm0, %xmm1 movsd %xmm2, %xmm0 call printf xor %rax, %rax add $8, %rsp ret .section .rodata .Lr: .double 5.0 .Lpi: .double 3.14159 .Lfmt: .string "The area of radius %f is %f\n" .end
沒有留言:
張貼留言