# [x86-16 ASM][1], IBM PC DOS, 23 bytes 03 F1 ADD SI, CX ; start at end of input string FD STD ; set LODSB direction to decrement DIGIT_LOOP: AC LODSB ; load next digit into AL, decrement SI 2C 30 SUB AL, '0' ; convert ASCII char to binary value F7 DA NEG DX ; flip DX to alternate odd/even index 78 06 JS EVEN ; if even index, do not double and sum digits D0 E0 SHL AL, 1 ; double the value D4 0A AAM ; BCD convert to split digits (ex: 18 = 12H --> 0108H) 02 DC ADD BL, AH ; add tens digit to running sum EVEN: 02 D8 ADD BL, AL ; add ones digit to running sum E2 ED LOOP DIGIT_LOOP 93 XCHG BX, AX ; sum is in BL, move to AL for conversion D4 0A AAM ; BCD convert AL, set ZF=1 if low digit is 0 Uses (abuses) the x86's BCD-to-binary instruction `AAM` to handle the individual digit splitting and `modulo 10` check. Input card num string pointer in `SI`, length in `CX`. Output: `ZF` if valid. **Example test program output:** [![enter image description here][4]][4] [Download LUHN.COM][5] IBM PC DOS test program. [1]: https://software.intel.com/sites/default/files/managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf [2]: http://www.fysnet.net/yourhelp.htm [3]: https://codegolf.stackexchange.com/questions/132981/tips-for-golfing-in-x86-x64-machine-code/181407#181407 [4]: https://i.sstatic.net/vOgkr.png [5]: https://stage.stonedrop.com/ppcg/LUHN.COM