2008年11月12日水曜日

asm習作

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
感想

  • 寝癖およびAT&T formatとintel formatの違いで頭がぐしゃぐしゃ。

  • divで割られるreigsterがedx:eax固定。恐怖のRISC脳はsrc/dst合計4つを想像する

  • test x xとかxor x xとか。恐怖のry




unsigned int
asm_gcd(unsigned int x, unsigned int y)
{
/* asm memo
* mnemonic: div
* to be diveded edx:eax
* diveded by source: r/m32
* result
* div -> eax
* mod -> edx
*/
/*
skelton
div, mod = divmod(x, y)
divmod(y, mod)
*/
/*
implementaion idea (intel format)
eax, edx = div(edx:eax, ecx)
mov eax, ecx; # next x(1)
mov ecx, edx; # next y
mov edx, 0; # next x(2)
loop if ecx:
return eax
*/
assert(x >= y);
__asm__ __volatile__(
"init: \n\t"
" xor %%edx,%%edx \n\t"
"while: \n\t"
" div %%ecx \n\t"
" mov %%ecx,%%eax \n\t"
" mov %%edx,%%ecx \n\t"
" xor %%edx,%%edx \n\t"
" cmp %%edx,%%ecx \n\t"
" jne while \n\t"
: "=a"(x):"a"(x),"c"(y));
return x;
}

unsigned int
w_gcd(unsigned int x, unsigned int y)
{
unsigned int z;
while(y){
z = y;
y = x%y;
x = z;
}
return x;
}

unsigned int
c_gcd(unsigned int x, unsigned int y)
{
if(y){
return c_gcd(y, x%y);
}
return x;
}

int
main(int argc, char**argv)
{
assert(c_gcd(1, 1) == 1);
assert(c_gcd(4, 2) == 2);
assert(c_gcd(4, 3) == 1);
assert(c_gcd(12, 3) == 3);
assert(w_gcd(1, 1) == 1);
assert(w_gcd(4, 2) == 2);
assert(w_gcd(4, 3) == 1);
assert(w_gcd(12, 3) == 3);
assert(asm_gcd(1, 1) == 1);
assert(asm_gcd(4, 2) == 2);
assert(asm_gcd(4, 3) == 1);
assert(asm_gcd(12, 3) == 3);
assert(asm_gcd(15, 3) == 3);
assert(asm_gcd(144, 64) == 16);
return 0;
}


ちなみに-O2でコンパイルするとw_gcdもc_gcdは同一のasmに落ちて、手で組んだコードとほぼ同じになる。末尾最適化とレジスタ割付の最適化はちゃんと行われているようだ

.globl w_gcd
.type w_gcd, @function
w_gcd:
.LFB28:
test %esi, %esi
mov %eax, %edi
jne .L7
jmp .L2
.p2align 4,,7
.L9:
mov %esi, %edx
.L7:
xor %edx, %edx
div %esi
mov %eax, %esi
test %edx, %edx
jne .L9
mov %eax, %esi
.L2:
rep ret



.globl c_gcd
.type c_gcd, @function
c_gcd:
.LFB29:
test %esi, %esi
mov %eax, %edi
jne .L17
jmp .L12
.p2align 4,,7
.L18:
mov %esi, %edx
.L17:
xor %edx, %edx
div %esi
mov %eax, %esi
test %edx, %edx
jne .L18
mov %eax, %esi
.L12:
rep ret

0 件のコメント: