MS-DOS machine code (.COM file), 63126 bytes - non-competing
Non-competing because a quine must not access its own source code.
A 126(A 63-byte variant would fulfillbe possible if the "not accessprogram was allowed to read its own source code" requirement!code.)
The 63 byte variant looksfirst half (63 bytes) of the program are code and look like this:
FC BE 00 01BE<3F>01 AC 50 88 C2 B4 02 CD 21 E8 1A 00 59
4E AC 81 FE 3F 01FE<7E>01 7C 03 BE 00 01BE<3F>01 38 C1 75 F2 FE
CA 75 EE 81 FE 00 01FE<3F>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
The second half (63 bytes) are data and are a 1:1 copy of the code.
(In the 63-byte variant reading its own code, the bytes marked with "<>" have different values and the second half of the program is not present.)
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
# 0x100:
cld # Ensure SI is being incremented
mov si, 0x100 programEnd # Move SI to the first byte of the copy 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 ...
cmp si, 2*programEnd-0x100
jl notEndOfProgram # ... the next byte to be loaded ...
mov si, 0x100 programEnd # ... 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 programEnd # 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:
## Place a copy of the code as data here ##