Gea-Suan Lin's BLOG

Saturday, October 28, 2006

Unix 環境下的 Inline Assembly

從大二修 Assembly 後就很久沒寫組語了,當時修的時候還是用 Intel 語法寫,就一直沒學到 AT&T 語法,後來從網路上看也只知道 src 與 dst 的位置通常是相反的,以及 register 前面要用 % 修飾,其他的像是記憶體的定址要怎麼寫都不知道,所以在 Unix 下一直不會寫 Assembly…

前幾天有個學弟剛好在寫作業,要用 MMX 計算一個整數 Vector (看做是 1*n 的 Matrix) 乘上整數 Matrix (n*n) 的結果 (其中 n 會是 4 的倍數,另外每個整數都是 16 bits),趁著這個機會摸索 GCC 裡要怎麼寫 Inline Assembly,以及 AT&T 語法與 Intel 語法不同的地方…

這是剛摸索出來怎麼寫,基本上請不要太要求… :p 編譯環境是 6.1 系統內附的 GCC (gcc version 3.4.4 [FreeBSD] 20050518)。

void matrixMMX(const unsigned int n,     const uint16_t const *vec, const uint16_t const *mat,     uint16_t *result) {     const unsigned int n2      // First empty the result array     bzero(result, sizeof(uint16_t) * n);      asm volatile("\         mov %1, %%edi;\         mov %3, %%ecx;\         mov %2, %%edx;\ loop1:\         mov %0, %%esi;\         push %%ecx;\         mov %4, %%ecx;\ loop2:\         movq (%%esi), %%mm0;\         pmaddwd (%%edi), %%mm0;\ \         movd %%mm0, %%eax;\         mov %%eax, %%ebx;\         shr $16, %%eax;\         add %%ax, %%bx;\         add %%bx, (%%edx);\ \         psrlq $32, %%mm0;\ \         movd %%mm0, %%eax;\         mov %%eax, %%ebx;\         shr $16, %%eax;\         add %%ax, %%bx;\ \         add %%bx, (%%edx);\ \         add $8, %%edi;\         add $8, %%esi;\         loop loop2;\ \         add $2, %%edx;\         pop %%ecx;\         loop loop1;\ \         emms;"::         "X"(vec), "X"(mat), "X"(result), "X"(n), "X"(n2):         "eax", "ebx", "ecx", "edx", "esi", "edi", "mm0"); }