| Uutiset | Koodikirjasto | Wiki | Keskustelut | FAQ | Info |
Suurin yhteinen tekijä assemblerillaZtane 14.05.07 22:50 Etsii annettujen 32-bittisten kokonaislukujen suurimman yhteisen tekijän (NASM, cdecl, 386+).
; 32-bit x86 assembly BITS 32 ; function entry global gcd gcd: ; load arguments to eax (a) and edx (b). mov eax, [esp + 4] mov edx, [esp + 8] ; cdecl, must save ebx push ebx xor ecx, ecx xor ebx, ebx inc ebx ; 1 ; check that eax and edx are non-zero test eax, eax jz bail_out test edx, edx jz bail_out ; main loop do_loop: test edx, edx jz end test edx, ebx jnz edx_odd ; edx (b) == even shr edx, 1 test eax, ebx ; eax odd - shr eax (gcd(a, b) = gcd(a, b/2) jnz do_loop ; eax is even as well - gcd(a, b) = 2gcd(a/2, b/2) shr eax, 1 inc ecx ; shift ++ jmp do_loop ; edx odd... edx_odd: test eax, ebx jnz eax_odd ; eax even - shr eax (gcd(a, b) = gcd(a/2, b) shr eax, 1 jmp do_loop eax_odd: ; both are odd... swap a, b (eax, edx) if b (edx) < a (eax)! cmp edx, eax jae do_sub xchg edx, eax do_sub: ; gcd(a, b) = gcd(a, (b - a) / 2) sub edx, eax shr edx, 1 jmp do_loop bail_out: ; returns 0 xor eax, eax end: ; edx = 0, eax contains gcd / 2^(ecx) ; now we have to shift left by ecx bits... shl eax, cl pop ebx ; result in eax, return ret Ztane 22:53 14.5.07 esittelee syt-algoritmin 32-bittisille luvuille asm-funktiona jota voidaan kutsua C:stä, prototyypillä C uint32_t gcd(uint32_t a, uint32_t b); Ztane 23:01 14.5.07 algoritmi siis sama kuin tässä: http://mureakuha.com/koodikirjasto/1010 kikka7 01:17 15.5.07 Annan miinusta koska oon niin kännissä. Ztane 08:27 15.5.07 haha xP Akheron 09:48 15.5.07 Pakko oli testata tämän tehokkuutta ja Python-version tehokkuutta. 8 sekunnissa assemblyversio jaksoi omalla koneellani laskea funktion 3e7 kertaa, kun samassa ajassa Python-versio jaksoi 2e5 kertaa. Laskenta suoritettiin joka kerta samoilla luvuilla, jotta mittaus olisi mahdollisimman reilu eikä lukujen arvonnasta tulisi overheadia. Ztane 11:34 15.5.07 itse asiassa huomasin tuossa, että tuota voi optimoida rankastikin, eli siirtää kokonaan pois noi kakkosella jakamiset eri silmukkaan - 2^n yhteisenä tekijänä voidaan todeta heti alkuun. editoitu: 16:47 15.5.07 glaas 16:24 15.5.07 Hieman herätti mielenkiintoa tuossa alussa ollut kommentti ettei ebx/ebp ole käytössä. Käsittääkseni jotta tuota voisi käytellä C:n kautta, ainoat 'vapaat' kokonaislukurekisterit ovat eax, ecx, edx. Muiden arvot olisi tallennettava alussa ja palautettava lopussa. Pikavilasulla tuo näyttäisi pätevän 32-bit win/linux/bsd/mac käyttiksiin. 64 bittisissä linux/bsd nuo vapaat ovatkin sitten rax,rcx,rdx,rsi,rdi,r8-r11 (mahtaisiko sekoittua näihin ;)) editoitu: 17:15 15.5.07 Ztane 17:10 15.5.07 hmm... eiks edi ja esi ollu muka... EDIT: argh: EBX, ESI, EDI, EBP, DS, ES, and SS pitää tallettaa... Akiro 11:36 16.5.07 kikka7 kirjoitti: Annan miinusta koska oon niin kännissä. Kaikki kommenttisi tuntuvat olevan yhtä rakentavia kuin tämä. Vaihda asiallisemmalle linjalle kiitos, eli ei tarvitse postata joka paikkaan jos ei ole mitään asiaa. |
![]() Haku
|