### code x86-64 pour résoudre le problème des N reines
### lit N sur l'entrée standard
###
### compilation manuelle du code C suivant
###
### 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:
pushq %rbp
movq %rsp, %rbp
movq $input, %rdi # premier argument de scanf = format
movq $q, %rsi # second argument de scanf = adresse pour n
xorq %rax, %rax # pas d'autres arguments
call scanf
xorq %rdi, %rdi # a = ~(~0 << n)
notq %rdi
movq (q), %rcx
salq %cl, %rdi # un décalage calculé doit utiliser %cl
notq %rdi
xorq %rsi, %rsi # b = 0
xorq %rdx, %rdx # c = 0
call t
movq $msg, %rdi # premier argument de printf = format
movq (q), %rsi # deuxième argument = n
movq %rax, %rdx # troisième argument = résultat
xorq %rax, %rax # pas d'autres arguments
call printf
xorq %rax, %rax # code de sortie 0 pour exit
popq %rbp
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
pushq %rbp
movq %rsp, %rbp
subq $48, %rsp # allouer 6 mots sur la pile
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
## note : on peut remplacer les six dernières instructions par
## andn %rcx, %rsi, %rcx (Logical AND NOT)
## andn %rcx, %rdx, %rcx
jmp loop_test
loop_body:
movq %rdi, 0(%rsp) # sauver a
movq %rsi, 8(%rsp) # sauver b
movq %rdx, 16(%rsp) # sauver c
movq %r8, 24(%rsp) # sauver d
movq %rcx, 32(%rsp) # sauver e
movq %rax, 40(%rsp) # sauver 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 # restaurer e
subq 24(%rsp), %rcx # -= d
movq 16(%rsp), %rdx # restaurer c
movq 8(%rsp), %rsi # restaurer b
movq 0(%rsp), %rdi # restaurer a
loop_test:
movq %rcx, %r8 # d <- e & -e
movq %rcx, %r9
negq %r9
andq %r9, %r8
## note : on peut remplacer les quatre dernières instructions par
## blsi %rcx, %r8 (Extract Lowest Set Isolated Bit)
jnz loop_body
addq $48, %rsp
popq %rbp
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: