;name: dealcards.asm
;
;build: nasm -felf64 dealcards.asm -o dealcards.o
; ld -s -melf_x86_64 -o dealcards dealcards.o
;
;description: Create a set of shuffled cards.
; This demo creates 20 sets of dealed cards
[list -]
%include "unistd.inc"
[list +]
;numbers are displayed wrong above 99
%define TOTAL_CARDS 52
bits 64
section .data
shuffledcards: times TOTAL_CARDS db 0
buffer: times 2 db 0
spacer: db " "
eol: db 0x0A
section .text
global _start
_start:
mov rdi,shuffledcards ;pointer to buffer for the shuffled cards
mov rsi,TOTAL_CARDS ;total cards to shuffle
call shuffle ;shuffle the cards
mov rdi,shuffledcards ;pointer to the cards
mov rsi,TOTAL_CARDS ;number of cards to show
call showCards ;show the cards
mov rsi,eol
mov rdx,1
call writeString ;print end of line
syscall exit,0
showCards:
;RDI : pointer to buffer with cards to show
;RSI : number of cards to show
mov rcx,rsi ; number of cards to show in rcx
mov rsi,rdi ; pointer to card buffer in rdi
xor rax,rax
.next:
lodsb
mov rbx,10
xor rdx,rdx
idiv rbx
or dl,"0"
mov byte[buffer+1],dl
mov rdx,2 ; length of output
or al,"0"
mov byte[buffer],al
push rcx
push rsi
mov rsi,buffer
mov rdx,3
call writeString
pop rsi
pop rcx
loopnz .next
ret
writeString:
;RSI : pointer to the string
;RDX : length of the string
syscall write,stdout
ret
shuffle:
;RDI : pointer to buffer where the cards must be stored
;RSI : total cards in a deck
mov rbx,rsi ;TOTAL_CARDS in bl
xor r8,r8
.newcard:
inc r8 ;increment counter
cmp r8,rbx ;TOTAL_CARDS reached?
jg .endshuffling
.tryagain:
rdtsc ;read the time stamp counter
shr rax,3 ;divide by 8, this an empirical value, without, the algorithm takes a long time for cards = 52, 20
;still don't know why
xor ah,ah
idiv bl ;tsc divided by TOTAL_OF_CARDS, modulo in RDX
and ah,ah
jne .check
mov ah,bl ;if remainder is zero, then remainder is the highest card
;loop through shuffledcards to check if card is already choosen
.check:
mov rsi,rdi
mov rcx,r8
.checknext:
lodsb ;AL has the card
and al,al
je .storecard
cmp al,ah
je .tryagain
loop .checknext
.storecard:
dec rsi
mov byte[rsi],ah
jmp .newcard
.endshuffling:
ret