view q.asm @ 2:eac01194cb9a tip

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

; A quine in 8086 assembly language (NASM source code) for DOS systems
; Public Domain, written 2011-06-13 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 "data_end:",13,10
        db "data_size equ $-data",13,10
end_size equ $-end

data:
        db "",13,10
        db "; A quine in 8086 assembly language (NASM source code) for DOS systems",13,10
        db "; Public Domain, written 2011-06-13 by C. Masloch",13,10
        db "",13,10
        db "        cpu 8086",13,10
        db "        org 100h",13,10
        db "",13,10
        db "start:",13,10
        db "        mov dx, data",13,10
        db "        mov cx, data_size",13,10
        db "        call disp_converted             ; display initial program source code",13,10
        db "",13,10
        db "        mov di, data",13,10
        db "loop:",13,10
        db "        mov dx, prefix",13,10
        db "        mov cx, prefix_size",13,10
        db "        call disp                       ; display data line prefix",13,10
        db "        mov dx, di                      ; -> remaining data",13,10
        db "        mov al, 10",13,10
        db "        mov cx, -1",13,10
        db "        repne scasb                     ; search for next LF in data",13,10
        db "        mov cx, di",13,10
        db "        dec cx",13,10
        db "        dec cx                          ; point to the CR,LF sequence",13,10
        db "        sub cx, dx                      ; size of this data line",13,10
        db "        call disp                       ; display the literal data",13,10
        db "        mov dx, suffix",13,10
        db "        mov cx, suffix_size",13,10
        db "        call disp                       ; display data line suffix",13,10
        db "        cmp di, data_end                ; at end?",13,10
        db "        jne loop                        ; not yet -->",13,10
        db "",13,10
        db "        mov dx, end",13,10
        db "        mov cx, end_size",13,10
        db "        call disp                       ; display data size calculation lines",13,10
        db "        mov ax, 4C00h",13,10
        db "        int 21h                         ; terminate process",13,10
        db "",13,10
        db "        ; Display message to standard output,",13,10
        db "        ;  convert all code 40h characters to double quotes",13,10
        db "        ;",13,10
        db "        ; INP:  dx-> message, length cx",13,10
        db "        ; OUT:  -",13,10
        db "        ; CHG:  ax, bx, dx, cx, si",13,10
        db "disp_converted:",13,10
        db "        mov si, dx",13,10
        db "        jcxz .done                      ; skip the loop -->",13,10
        db ".loop:",13,10
        db "        lodsb",13,10
        db "        cmp al, 40h                     ; code 40h character ?",13,10
        db "        jne .next                       ; no -->",13,10
        db "        push cx",13,10
        db "        push si",13,10
        db "        call .disp_til_si_dec           ; display message in front of code 40h character",13,10
        db "        mov dx, doublequote",13,10
        db "        mov cx, doublequote_size",13,10
        db "        call disp                       ; display the code 40h character replacement",13,10
        db "        pop dx                          ; -> remaining message behind code 40h character",13,10
        db "        pop cx",13,10
        db ".next:",13,10
        db "        loop .loop                      ; process remaining characters if any -->",13,10
        db ".done:",13,10
        db "        inc si",13,10
        db ".disp_til_si_dec:",13,10
        db "        lea cx, [si-1]",13,10
        db "        sub cx, dx",13,10
        db "",13,10
        db "        ; Display message to standard output",13,10
        db "        ;",13,10
        db "        ; INP:  dx-> message, length cx",13,10
        db "        ; OUT:  -",13,10
        db "        ; CHG:  ax, bx",13,10
        db "disp:",13,10
        db "        mov bx, 1",13,10
        db "        mov ah, 40h",13,10
        db "        int 21h",13,10
        db "        retn",13,10
        db "",13,10
        db "doublequote:",13,10
        db "        db '@'",13,10
        db "doublequote_size equ $-doublequote",13,10
        db "",13,10
        db "prefix:",13,10
        db "        db '        db @'",13,10
        db "prefix_size equ $-prefix",13,10
        db "",13,10
        db "suffix:",13,10
        db "        db '@,13,10',13,10",13,10
        db "suffix_size equ $-suffix",13,10
        db "",13,10
        db "end:",13,10
        db "        db @data_end:@,13,10",13,10
        db "        db @data_size equ $-data@,13,10",13,10
        db "end_size equ $-end",13,10
        db "",13,10
        db "data:",13,10
data_end:
data_size equ $-data