### código x86-64 para resolver o problema das N rainhas
### lê N da entrada standard
###
### compilação manual do código C seguinte
###
### int t(int a, int b, int c) {
###   int f = 1;
###   if (a) {
###     int d, e = a & ~b & ~c;
###     f = 0;
###     while (d = e & -e) {
###       f += t(a - d, (b + d) * 2, (c + d) / 2);
###       e -= d;
###     }
###   }
###   return f;
### }
###
### main() {
###   int n;
###   scanf("%d", &n);
###   printf("queens(%d) = %d\n", n, t(~(~0 << n), 0, 0));
### }

        .text
	.globl	main
main:
        movq    $input, %rdi    # primeiro argumento de scanf = format
        movq    $q, %rsi        # segundo argumento de scanf = endereço para n
        xorq    %rax, %rax      # não há outros argumentos
        call    scanf

        xorq    %rdi, %rdi      # a = ~(~0 << n)
        notq    %rdi
        movq    (q), %rcx
        salq    %cl, %rdi       # um shift calculado deve usar %cl
        notq    %rdi
        xorq    %rsi, %rsi      # b = 0
        xorq    %rdx, %rdx      # c = 0
        call    t

	movq	$msg, %rdi      # primeiro argumento de printf = format
        movq    (q), %rsi       # segundo argumento = n
        movq    %rax, %rdx      # terceiro argumento = resultado
        xorq    %rax, %rax      # não há outros argumentos
	call	printf
        xorq    %rax, %rax      # código de saída 0 para exit
	ret

        ##  t(a:rdi, b:rsi, c:rdx)
        ##     e:rcx, d:r8, f:rax
t:
        movq    $1, %rax        # f <- 1
        testq   %rdi, %rdi      # a = 0 ?
        jz      t_return
        subq    $48, %rsp       # alocar 6 palavras/words na pilha
        xorq    %rax, %rax      # f <- 0
        movq    %rdi, %rcx      # e <- a & ~b & ~c
        movq    %rsi, %r9
        notq    %r9
        andq    %r9, %rcx
        movq    %rdx, %r9
        notq    %r9
        andq    %r9, %rcx
        jmp     loop_test
loop_body:
        movq    %rdi,  0(%rsp) # gravar a
        movq    %rsi,  8(%rsp) # gravar b
        movq    %rdx, 16(%rsp) # gravar c
        movq    %r8,  24(%rsp) # gravar d
        movq    %rcx, 32(%rsp) # gravar e
        movq    %rax, 40(%rsp) # gravar f
        subq    %r8, %rdi      # a <- a-d
        addq    %r8, %rsi      # b <- (b+d)<<1
        salq    $1, %rsi
        addq    %r8, %rdx      # c <- (c+d)>>1
        shrq    $1, %rdx
        call    t              # t(a-d, (b+d)<<1, (c+d)>>1)
        addq    40(%rsp), %rax  # f += t(...)
        movq    32(%rsp), %rcx # reconstituir e
        subq    24(%rsp), %rcx #  -= d
        movq    16(%rsp), %rdx # reconstituir c
        movq     8(%rsp), %rsi # reconstituir b
        movq     0(%rsp), %rdi # reconstituir a
loop_test:
        movq    %rcx, %r8      # d <- e & -e
        movq    %rcx, %r9
        negq    %r9
        andq    %r9, %r8
        jnz     loop_body
        addq    $48, %rsp
t_return:
        ret

        .data
msg:
	.string	"queens(%d) = %d\n"
input:
        .string "%d"
q:
        .quad   0

## Local Variables:
## compile-command: "gcc queens.s -o queens"
## End: