view halfqt.asm @ 2:eac01194cb9a tip

annotated qt variant (annotqt)
author C. Masloch <pushbx@38.de>
date Thu, 25 Oct 2012 18:40:16 +0200
parents cc13c6671f25
children
line wrap: on
line source

; A quine in 8086 assembly language (NASM source code) for DOS systems
; Public Domain, written 2011-06-13 and 2012-10-25 by C. Masloch

        cpu 8086
        org 100h

start:
        mov dx, data
        mov cx, data_size
        call disp_converted             ; display initial program source code

        mov di, data
loop:
        mov dx, prefix
        mov cx, prefix_size
        call disp                       ; display data line prefix
        mov dx, di                      ; -> remaining data
        mov al, 10
        mov cx, -1
        repne scasb                     ; search for next LF in data
        mov cx, di
        dec cx
        dec cx                          ; point to the CR,LF sequence
        sub cx, dx                      ; size of this data line
        call disp                       ; display the literal data
        mov dx, suffix
        mov cx, suffix_size
        call disp                       ; display data line suffix
        cmp di, data_end                ; at end?
        jne loop                        ; not yet -->

        mov dx, end
        mov cx, end_size
        call disp                       ; display data size calculation lines
        mov ax, 4C00h
        int 21h                         ; terminate process

        ; Display message to standard output,
        ;  convert all code 40h characters to double quotes
        ;
        ; INP:  dx-> message, length cx
        ; OUT:  -
        ; CHG:  ax, bx, dx, cx, si
disp_converted:
        mov si, dx
        jcxz .done                      ; skip the loop -->
.loop:
        lodsb
        cmp al, 40h                     ; code 40h character ?
        jne .next                       ; no -->
        push cx
        push si
        call .disp_til_si_dec           ; display message in front of code 40h character
        mov dx, doublequote
        mov cx, doublequote_size
        call disp                       ; display the code 40h character replacement
        pop dx                          ; -> remaining message behind code 40h character
        pop cx
.next:
        loop .loop                      ; process remaining characters if any -->
.done:
        inc si
.disp_til_si_dec:
        lea cx, [si-1]
        sub cx, dx

        ; Display message to standard output
        ;
        ; INP:  dx-> message, length cx
        ; OUT:  -
        ; CHG:  ax, bx
disp:
        mov bx, 1
        mov ah, 40h
        int 21h
        retn

doublequote:
        db '"'
doublequote_size equ $-doublequote

prefix:
        db 'db "'
prefix_size equ $-prefix

suffix:
        db '",13,10',13,10
suffix_size equ $-suffix

end:
        db "o:",13,10
        db "D equ $-d",13,10
end_size equ $-end

data:
        db ";86dos/nasm/quine",13,10
        db ";public-domain,20110613,20121025,ecm",13,10
        db "cpu 8086",13,10
        db "org 256",13,10
        db "a:",13,10
        db "mov dx,d",13,10
        db "mov cx,D",13,10
        db "call c",13,10
        db "mov di,d",13,10
        db "l:",13,10
        db "mov dx,p",13,10
        db "mov cx,P",13,10
        db "call u",13,10
        db "mov dx,di",13,10
        db "mov al,10",13,10
        db "mov cx,-1",13,10
        db "repne scasb",13,10
        db "mov cx,di",13,10
        db "dec cx",13,10
        db "dec cx",13,10
        db "sub cx,dx",13,10
        db "call u",13,10
        db "mov dx,s",13,10
        db "mov cx,S",13,10
        db "call u",13,10
        db "cmp di,o",13,10
        db "jne l",13,10
        db "mov dx,e",13,10
        db "mov cx,E",13,10
        db "call u",13,10
        db "mov ax,4C00h",13,10
        db "int 33",13,10
        db "c:",13,10
        db "mov si,dx",13,10
        db "jcxz .d",13,10
        db ".l:",13,10
        db "lodsb",13,10
        db "cmp al,64",13,10
        db "jne .n",13,10
        db "push cx",13,10
        db "push si",13,10
        db "call .t",13,10
        db "mov dx,q",13,10
        db "mov cx,Q",13,10
        db "call u",13,10
        db "pop dx",13,10
        db "pop cx",13,10
        db ".n:",13,10
        db "loop .l",13,10
        db ".d:",13,10
        db "inc si",13,10
        db ".t:",13,10
        db "lea cx,[si-1]",13,10
        db "sub cx,dx",13,10
        db "u:",13,10
        db "mov bx,1",13,10
        db "mov ah,64",13,10
        db "int 33",13,10
        db "retn",13,10
        db "q:",13,10
        db "db '@'",13,10
        db "Q equ $-q",13,10
        db "p:",13,10
        db "db 'db @'",13,10
        db "P equ $-p",13,10
        db "s:",13,10
        db "db '@,13,10',13,10",13,10
        db "S equ $-s",13,10
        db "e:",13,10
        db "db @o:@,13,10",13,10
        db "db @D equ $-d@,13,10",13,10
        db "E equ $-e",13,10
        db "d:",13,10
data_end:
data_size equ $-data