Skip to content

Instantly share code, notes, and snippets.

@xavery
Last active November 8, 2015 20:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xavery/e6c5c0d0116dfbdb33a1 to your computer and use it in GitHub Desktop.
Save xavery/e6c5c0d0116dfbdb33a1 to your computer and use it in GitHub Desktop.
bits 64
global factorial
; uint64_t factorial(uint n [edi],bool *valid [rsi])
factorial:
mov [rsi], dword 1 ; assume no overflow until proven otherwise
cmp edi, 1
jbe .ret1
cmp edi, 21
jae .overflow ; result will not fit in a uint64
mov eax, edi
sub edi, 1
.loop:
mul rdi
sub edi, 1
jnz .loop
ret ; happy ending
.overflow:
mov [rsi], dword 0 ; rax contains garbage now : mark as invalid
ret
.ret1:
mov eax, 1
ret
#include <assert.h>
#include <limits.h>
#include <stdint.h>
uint64_t factorial(unsigned int, int*);
int main(void)
{
int valid;
assert(factorial(0, &valid) == 1 && valid == 1);
assert(factorial(1, &valid) == 1 && valid == 1);
assert(factorial(5, &valid) == 120 && valid == 1);
assert(factorial(15, &valid) == 1307674368000 && valid == 1);
factorial(UINT_MAX, &valid);
assert(valid == 0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment