8
Liebranca
74d

I'm delirious so here's your daily dose of fuck:

```fasm
; --- * --- * ---
; 64-bit byte-by-byte mash

macro clamp_u8 {
mov cl,$08;
mov rdx,rax;
rept 8 \{
rol rdx,cl;
xor al,dl;
\};
};

; --- * --- * ---
; give 8-bit random seed

macro prng_u8 {
rdtsc;
shl rdx,32;
or rax,rdx;
clamp_u8;
};

; --- * --- * ---
; roll dice

d20: prng_u8;

; x%20, according to gcc ;>
mov edi,eax;
mov eax,-51;
mul dil;
shr ax,12;
lea eax,[rax+rax*4];
lea edx,[0+rax*4];
mov eax,edi;
sub eax,edx;

; discard high and give
and rax,$FF;
ret;
```

I guess `d20` could be inlined too but I thought it'd be too much.

Is it faster than straight C? Probably not. But it's way lighter, so it loads faster. Below five hundred bytes mother fucker.

Now if you'll excuse me, I'll go sit in the darkness repeteadly typing roll 1d20 on the terminal. For reasons.

Comments
  • 1
    Now do it for Arm! j/k
  • 0
    fuck
  • 4
    I’m not masochistic enough to read assembler, sorry :)
  • 1
    Wait, rolling 1d20? I'm hyped, how do I use it?
  • 1
    @c3r38r170 call d20, and you get a random number between 0 and 19 in rax.

    For use in the terminal, you have this value determine what's printed to stdout. There's two basic ways you can do this without libc. First one is fetch from a table; you just read from const char* array in ROM, get the length, and write to stdout.

    The second way is more flexible, but you have to hand-roll an itoa. In essence, you reserve some memory in the stack to use as a string, and translate the unsigned integer in rax to ascii. For instance, 15 ($0F) has to be output as $0A3531, note the newline at the end.

    If we know we won't be outputting strings longer than N characters then we can just write null to the memory we reserved in the stack, and never get the actual length -- just output the whole thing.

    But I was thinking of writing the whole set of dice for D&D, so if you'd like, I'll just do that and share the file. Under GPL3, of course ;>
  • 2
    @Lensflare Assembly*, as in 'assembly language'. Bro do you even lock cmpxchg dword [rdi],edx?
  • 1
    @Liebranca Hmu when you do, please!
  • 0
  • 0
    @c3r38r170 lmao I'm so sorry it took me this long, I'm just using this to test my compiler and got a *little* bit carried away.

    Anyhoo, here's a full version for Linux: https://gist.github.com/Liebranca/...

    For a different system, you'd have to replace the syscalls and the bit where the commandline arguments are read.

    To use it: roll NdX, where N is the number of dice (from 0x1 to 0xB), and X is the sides. I implemented d4, d6, d8, d10, d12, d20, and d% (d100).

    You can have multiple rolls in one call, eg roll 1d4 3d6 8d10 Bd% or what have you. It'll give them in order, each in a new line.

    100% under GPL.
Add Comment