# [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