Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %include "io.inc"
- section .bss
- n resd 1
- k resd 1
- res resd 1
- i resd 1
- Cn resd 1
- Ck resd 1
- Cres resd 1
- section .data
- m dd -1
- r dd 0
- section .text
- global CMAIN
- CMAIN:
- GET_UDEC 4, [n]
- GET_UDEC 4, [k]
- mov eax, [n] ; i = n
- cmp eax, 2 ;
- jb .EXIT_1 ; if (n < 2) { return k <= 1 & (n != 0) & ~k; }
- mov ebx, [m]
- .L1:
- inc ebx ; m++
- shr eax, 1 ; i >>= 1
- jnz .L1
- mov [m], ebx
- mov eax, 1 ;
- mov ecx, [m] ;
- dec ecx ;
- shl eax, cl ; i = 1 << (m - 1);
- mov ebx, [r]
- test eax, eax
- jz .BL2 ; if (i == 0) goto BL2;
- test eax, [n] ; n & i
- jnz .BL2
- .L2:
- inc ebx ; r++
- shr eax, 1 ; i >>= 1
- jz .BL2
- test eax, [n] ; n & i
- jz .L2
- .BL2:
- mov [r], ebx
- mov eax, [m] ;
- mov [Cn], eax ; Cn = m;
- mov eax, [k] ;
- inc eax ;
- mov [Ck], eax ; Ck = k + 1;
- cmp eax, [Cn] ;
- ja .M1 ; if (Ck > Cn) goto M1;
- shl eax, 1
- cmp eax, [n]
- jbe .S1 ; if (Ck * 2 <= n) goto S1;
- mov eax, [Cn] ;
- sub eax, [Ck] ;
- mov [Ck], eax ; Ck = Cn - Ck;
- .S1:
- test eax, eax
- jnz .S2 ; if (Ck != 0) goto S2;
- mov eax, 1 ;
- mov [res], eax ; res = 1
- jmp .M1 ; if (Ck == 0) { res = 1; goto M1; }
- .S2:
- mov eax, [Cn] ; res = Cn
- mov ebx, 2 ; i = 2
- cmp ebx, [Ck] ; i - Ck
- ja .BL3 ; if (i > Ck) goto BL3;
- .L3:
- mov ecx, [Cn] ;
- sub ecx, ebx ; Cn - i
- inc ecx ; Cn - i + 1
- mul ecx ; res *= (Cn - i + 1);
- div ebx ; res /= i
- inc ebx ; i++
- cmp ebx, [Ck] ; i - Ck
- jbe .L3
- .BL3:
- mov [res], eax
- .M1:
- mov ecx, [m] ;
- mov eax, 1 ;
- shl eax, cl ;
- xor eax, [n] ;
- mov [n], eax ; n ^= (1 << m);
- mov eax, [k] ;
- sub eax, [r] ;
- mov [k], eax ; k -= r;
- mov eax, [m] ;
- dec eax ;
- sub eax, [r] ;
- mov [m], eax ; m -= (r + 1);
- xor eax, eax ;
- mov [r], eax ; r = 0
- inc eax ;
- mov ecx, [m] ;
- dec ecx ;
- shl eax, cl ; i = 1 << (m - 1);
- mov ebx, [r]
- test eax, eax
- jz .BL4
- test eax, [n] ; n & i
- jnz .BL4
- .L4:
- inc ebx ; r++
- shr eax, 1 ; i >>= 1
- jz .BL4
- test eax, [n] ; n & i
- jz .L4
- .BL4:
- mov [r], ebx
- ;PRINT_UDEC 4, res
- ;NEWLINE
- ;PRINT_UDEC 4, n
- ;NEWLINE
- ;PRINT_UDEC 4, k
- ;NEWLINE
- ;PRINT_UDEC 4, r
- ;NEWLINE
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- .L5:
- mov eax, [n] ;
- test eax, eax ; n & n
- jz .EXIT_2 ; if (n == 0) { return res + (k == 0); }
- mov eax, [k] ;
- test eax, eax ; k & k
- jz .EXIT_3 ; if (k == 0) { return res + (n == (1 << (m + 1)) - 1); }
- mov eax, [m] ;
- mov [Cn], eax ; Cn = m;
- mov eax, [k] ;
- dec eax ;
- mov [Ck], eax ; Ck = k - 1;
- cmp eax, [Cn] ;
- ja .M2 ; if (Ck > Cn) { goto M2; }
- shl eax, 1 ;
- cmp eax, [n] ;
- jbe .S3 ; if (Ck * 2 <= n) goto S3;
- mov eax, [Cn] ;
- sub eax, [Ck] ;
- mov [Ck], eax ; if (Ck * 2 > n) { Ck = Cn - Ck; }
- .S3:
- test eax, eax
- jnz .S4 ; if (Ck != 0) goto S4;
- mov eax, [res] ;
- inc eax ;
- mov [res], eax ; res += 1
- jmp .M2 ; if (Ck == 0) { res += 1; goto M2; }
- .S4:
- mov eax, [Cn] ; Cres = Cn
- mov ebx, 2 ; i = 2
- cmp ebx, [Ck] ; i - Ck
- ja .BL6 ; if (i > Ck) goto BL6;
- .L6:
- mov ecx, [Cn]
- inc ecx ; Cn + 1
- sub ecx, ebx ; Cn - i + 1
- mul ecx ; Cres *= (Cn - i + 1)
- div ebx ; Cres /= i
- inc ebx ; i ++
- cmp ebx, [Ck] ; i - Ck
- jbe .L6
- .BL6:
- add eax, [res] ;
- mov [res], eax ; res += Cres;
- .M2:
- mov eax, 1 ;
- mov ecx, [m] ;
- shl eax, cl ;
- xor eax, [n] ;
- mov [n], eax ; n ^= (1 << m);
- mov eax, [k] ;
- sub eax, [r] ;
- mov [k], eax ;k -= r;
- mov eax, [m] ;
- dec eax ;
- sub eax, [r] ;
- mov [m], eax ; m -= (r + 1);
- xor eax, eax ;
- mov [r], eax ; r = 0
- inc eax ;
- mov ecx, [m] ;
- dec ecx ;
- shl eax, cl ; i = 1 << (m - 1);
- mov ebx, [r]
- test eax, eax
- jz .BL7
- test eax, [n]
- jnz .BL7
- .L7:
- inc ebx ; r++
- shr eax, 1 ; i >>= 1
- jz .BL7
- test eax, [n] ; n & i
- jz .L7
- .BL7:
- mov [r], ebx
- jmp .L5
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- .EXIT_3:
- ;PRINT_STRING "EXIT 3"
- ; NEWLINE
- mov ebx, 1
- mov ecx, [m] ; m
- inc ecx ; m + 1
- shl ebx, cl ; (1 << (m + 1))
- dec ebx ; (1 << (m + 1)) - 1
- xor eax, eax
- cmp ebx, [n]
- sete al ; n == (1 << (m + 1)) - 1
- add eax, [res] ; res + (n == (1 << (m + 1)) - 1)
- jmp .MAIN_EXIT
- .EXIT_2:
- ; PRINT_STRING "EXIT 2"
- ; NEWLINE
- xor eax, eax
- mov ebx, [k]
- test ebx, ebx ; k & k
- setz al
- add eax, [res]
- jmp .MAIN_EXIT
- .EXIT_1:
- ; PRINT_STRING "EXIT 1"
- ; NEWLINE
- test eax, eax
- cmovz eax, [r]
- jz .MAIN_EXIT
- mov eax, [k]
- cmp eax, 1
- cmova eax, [r]
- ja .MAIN_EXIT
- cmove eax, [r]
- je .MAIN_EXIT
- mov eax, 1
- .MAIN_EXIT:
- PRINT_UDEC 4, eax
- xor eax, eax
- ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement