## MS-DOS machine code (.COM file), 63 bytes ##

I'm not sure if it is valid to write quines in machine code so I'm not sure if this solution is a valid solution because machine code can easily read itself.

If it's not allowed the code (here in hexadecimal) is non-competing:

    FC BE 00 01 AC 50 88 C2 B4 02 CD 21 E8 1A 00 59
    4E AC 81 FE 3F 01 7C 03 BE 00 01 38 C1 75 F2 FE
    CA 75 EE 81 FE 00 01 75 DB 8A 16 00 80 31 C0 8E
    D8 31 C9 AC 00 C2 E2 FB 0E 1F 88 16 00 80 C3

I'm also not sure about the random generator's probability distribution:

The program uses the fact that the clock counters and other information modified by interrupts are stored in segment 0 to generate random numbers.

Examples for outputs generated are:

    FC BE 00 01 7C 03 BE 00 80 C3

    FC BE 00 01 38 C1 75 F2 FE 00 80 31 C9 AC 81 FE 00 80 C3

    FC BE 00 01 38 C1 75 EE 81 FE 00 01 38 C1 75 EE 81 FE CA
    75 F2 FE 00 01 75 F2 FE 00 80 C3

    FC BE 00 C2 B4 02 CD 21 E8 1A 00 01 7C 03 BE 00 59 4E AC
    81 FE 3F 01 AC 81 FE 3F 01 7C 03 BE 00 01 7C 03 BE 00 01
    AC 81 FE 3F 01 7C 03 BE 00 80 C3

Converted to assembly code the program looks like this:

        cld                # Ensure SI is being incremented
        mov si, 0x100      # Move SI to the first byte of the program
    nextOutput:
        lodsb              # Load one byte of the program ...
        push ax            # ... save it to the stack ...
        mov dl, al         # ... and output it!
        mov ah, 2
        int 0x21
        call pseudoRandom  # Create a random number (in DL)
        pop cx             # Take the stored byte from the stack
        dec si             # Go back to the last byte loaded
    nextSearch:
        lodsb              # Load the next byte
        cmp si, programEnd # If we loaded the last byte ...
        jl notEndOfProgram # ... the next byte to be loaded ...
        mov si, 0x100      # ... is the first byte of the program.
    notEndOfProgram:
        cmp cl, al         # If the byte loaded is not equal to ...
                           # ... the last byte written then ...
        jne nextSearch     # ... continue at nextSearch!
        dec dl             # Decrement the random number and ...
        jnz nextSearch     # ... continue at nextSearch until the ...
                           # ... originally random number becomes zero.
        cmp si, 0x100      # If the last byte read was not the last byte ...
        jnz nextOutput     # ... of the program then output the next ...
                           # ... byte!

        # Otherwise fall through to the random number generator
        # whose "RET" instruction will cause the program to stop.        

        # The random number generator:
    pseudoRandom:
        mov dl, [0x8000]   # Load the last random number generated
                           # (Note that this is uninitialized when
                           # this function is called the first time)
        xor ax, ax         # We use segment 0 which contains the ...
        mov ax, ds         # ... clock information and other data ...
                           # ... modified by interrupts!
        xor cx, cx         # Prepare for 0x10000 loops so ...
                           # ... all bytes in the segment are processed ...
                           # ... once and the value of SI will be ...
                           # ... unchanged in the end!
    randomNext:
        lodsb              # Load one byte
        add dl, al         # Add that byte to the next random number
        loop randomNext    # Iterate over all bytes
        push cs            # Restore the segment
        pop ds
        mov [0x8000], dl   # Remember the random number
        ret                # Exit sub-routine

    programEnd: