bootstrapping from COPY CON

Kragen Javier Sitaker kragen at canonical.org
Mon Apr 11 12:10:15 EDT 2011


In <http://boston.conman.org/2009/11/05.1>, “The dinosaur that I am”,
Sean Conner (spc476) suggests a sort of silly bare-metal problem...

> to most programmers, even a simple text editor is a crutch.
> 
> Imagine being given a 1982 era IBM PC with a floppy drive and a
> single disk that contains a bootable MS-DOS system with IO.SYS,
> MSDOS.SYS and COMMAND.COM (the minimum required to boot to a usable
> (for various values of “usable”) system at the time) and a stack of
> reference materials. Your goal (assuming you are a programmer) is to
> write a program that does something simple, like, play a game
> (however badly) of tic-tac-toe. No editor. No assembler. No
> compiler. No linker. Just COMMAND.COM and a stack of reference
> materials.

After some discussion at
<http://news.ycombinator.com/item?id=2428485>, I thought I would try
it out.

Hexadecimal input program enterable with COPY CON: 23 bytes
-----------------------------------------------------------

Well, step zero of bootstrapping from nothing on MS-DOS involves COPY
CON.  (If you don’t have EDLIN or DEBUG, say.). What do you write with
COPY CON?

Well, probably something that is a better alternative to COPY CON.
Say, something that lets you enter hex or octal, as short as possible
so that you have some chance of being able to type it without an
error.  With that in mind, I think it's probably okay to require the
use of JKLMNO instead of ABCDEF for the hex digits past 9.

A C version might look like this:

    int main(int argc, char **argv) {
      for (;;) {
        char c = getchar();
        if (c == '.') return 0;
        char d = getchar();
        putchar(((c & 0xf) << 4) | (d & 0xf));
      }
    }

getchar() is probably best as:
Int 21/AH=01h - DOS 1+ - READ CHARACTER FROM STANDARD INPUT, WITH ECHO
(which sticks the character into AL)

and putchar() is 
Int 21/AH=02h - DOS 1+ - WRITE CHARACTER TO STANDARD OUTPUT
(which takes the character to write in DL).

and for `return`, a simple RET is probably adequate, although there’s
an int-21 function for this too.  However, the purpose of this program
is to be run successfully only once, to create the next stage in the
bootstrap, so it’s probably adequate to exit by rebooting the
computer, as long as the output has made it to the filesystem, which
you can probably ensure by making it voluminous enough.  When I tested
it in Dosbox, Dosbox flushed its output to the filesystem when Dosbox
exited.  If not, you could add five bytes (3c 1b 74 XX ... c3) to exit
when the program sees an ESC.

So an assembly version of this program in gas syntax would look like
this:

            .code16
            .org 0x100

    loop:   mov $1, %ah                # read high nibble
            int $0x21
            and $0xf, %al
            mov %al, %dl
            shl $4, %dl

            int $0x21                  # read low nibble
            and $0xf, %al
            add %ax, %dx

            mov $0x2, %ah              # write output byte
            int $0x21
            jmp loop

An earlier version of this used `or %al, %dl`, but that produces a
backspace byte 08, which turns out to be impossible to enter with COPY
CON.  (So are 0D, CR, and 00, NUL.)  I’m glad I had other tools handy
to tell me what was wrong.

Here’s a handy shell script to assemble programs like this on Linux,
although our 1982 prisoner would be doing the assembly by hand
instead:

    #!/bin/sh
    set -ve
    base=${1%.s}
    as -R "$1" -o "$base.o"
    objcopy -O binary "$base.o" "$base.com.0"
    dd if="$base.com.0" bs=256 skip=1 > "$base.com"
    objdump -m i8086 -b binary -D "$base.com"

This assembles the above to the following:

    kragen at VOSTRO9:~/devel/misc$ objdump -m i8086 -b binary -D hexconv.com

    hexconv.com:     file format binary


    Disassembly of section .data:

    00000000 <.data>:
       0:	b4 01                	mov    $0x1,%ah
       2:	cd 21                	int    $0x21
       4:	24 0f                	and    $0xf,%al
       6:	88 c2                	mov    %al,%dl
       8:	c0 e2 04             	shl    $0x4,%dl
       b:	cd 21                	int    $0x21
       d:	24 0f                	and    $0xf,%al
       f:	01 c2                	add    %ax,%dx
      11:	b4 02                	mov    $0x2,%ah
      13:	cd 21                	int    $0x21
      15:	eb e9                	jmp    0x0
    kragen at VOSTRO9:~/devel/misc$ od -t u1 !$
    od -t u1 hexconv.com
    0000000 180   1 205  33  36  15 136 194 192 226   4 205  33  36  15   1
    0000020 194 180   2 205  33 235 233
    0000027
    kragen at VOSTRO9:~/devel/misc$ xxd < !$
    xxd < hexconv.com
    0000000: b401 cd21 240f 88c2 c0e2 04cd 2124 0f01  ...!$.......!$..
    0000010: c2b4 02cd 21eb e9                        ....!..

That’s 23 bytes, and I was able to enter it into Dosbox with COPY CON,
Alt, and the keypad on the first try, even though it doesn’t contain
many printable characters.  You can’t see what you’re typing, but you
can TYPE it afterwards to see if you got the right values, using a
reference like <http://www.ascii-codes.com/>.

I was able to use it to reproduce itself on stdout by typing the hex
version into its input: K401LM21240o88L2 etc.  It doesn’t support
backspace, so you have to type that very carefully! I think you could
write a version that does support backspace by using INT 21h AH=0Ah,
buffered input.

Note that this wouldn’t actually have worked in 1982.  According to
[Ralf Brown’s interrupt list][0], MS-DOS 1.0 did not support
redirecting standard output; that was a feature added in MS-DOS 2.0,
which [didn’t come out until 1983][1].  A version of this program that
explicitly opened an output file using the FCB functions from CP/M ---
the only ones supported in MS-DOS 1.0 --- would have been a real pain.
It probably would be easier to write something that overwrites a
floppy disk boot sector with INT 13h AH=03h, but then you don’t have a
filesystem.

[0]: http://www.ctyme.com/intr/rb-2554.htm
[1]: http://en.wikipedia.org/wiki/Timeline_of_x86_DOS_operating_systems

Octal input, with exit: 39 bytes
--------------------------------

Here’s an octal version with a sort of backspace and an exit command,
which you ought to be able to enter using the previous version:

            ## Input bytes in octal and write them to stdout.
            .org 0x100
            .code16
    start:  xor %dx, %dx            # unnecessary first time
    loop:   mov $0x01, %ah          # input char
            int $0x21               
            cmp $32, %al            # is input space?
            je putc
            cmp $8, %al
            je bs
            cmp $27, %al            # ESC to finish
            je done
            shl $3, %dl
            and $7, %al
            or %al, %dl
            jmp loop

    putc:   mov $0x02, %ah
            int $0x21
            jmp start

    bs:     shr $3, %dl
            jmp loop

    done:   ret                     # use CP/M compatibility exit

It’s 39 bytes:

    0000000: 31d2 b401 cd21 3c20 740d 3c08 740f c0e2  1....!< t.<.t...
    0000010: 0324 0708 c2eb ebb4 02cd 21eb e3c0 ea03  .$........!.....
    0000020: ebe0                                     ..

Recoding that to the form that our hexadecimal entry program expects
on input is simple with Perl:

    kragen at VOSTRO9:~/devel/misc$ perl -e 'undef $/; $_=<>; $_ = unpack "H*", $_; tr/a-f/jkLmno/; print $_, "\n"' octalinput.com
    31m2k401Lm213L2074113L0874133L1k7414L0n203240708L2nkn7k402Lm21nkmoL0nj03nkmLL3

I was able to enter that successfully on the second try using the
previous program.  Then I was able to reproduce it successfully with
itself, by entering the bytes in octal instead of hexadecimal:

    kragen at VOSTRO9:~/devel/misc$ od -t o1 octalinput.com
    0000000 061 322 264 001 315 041 074 040 164 021 074 010 164 023 074 033
    0000020 164 024 300 342 003 044 007 010 302 353 347 264 002 315 041 353
    0000040 337 300 352 003 353 334 303
    0000047

I did have to use the backspace once while doing that, and I was happy
to see that it worked.

Octal dump: 42 bytes
--------------------

Another couple of next little programs to write would be something to
do hex or octal dumps of input files (the 8086 instruction set is a
lot more readable in octal than in hexadecimal or decimal), and then
something that would allow you to edit a file interactively, so that
you could correct errors and make modified versions of existing
programs.

An octal dump program might look like this...

            .org 0x100
            .code16
            mov $0x101, %cx         # number of bytes to dump
    start:  mov $0x01, %ah
            int $0x21

            mov $0x02, %ah
            call dump
            mov $32, %dl
            int $0x21
            loop start
            ret

    dump:   test %al, %al
            jz base
            push %ax
            shr $3, %al
            call dump
            pop %ax
    base:   mov %al, %dl
            and $7, %dl
            add $48, %dl
            int $0x21
            ret

That works out to 42 bytes:

    kragen at VOSTRO9:~/devel/misc$ od -t o1 octaldump2.com
    0000000 271 001 001 264 001 315 041 264 002 350 007 000 262 040 315 041
    0000020 342 361 303 204 300 164 010 120 300 350 003 350 365 377 130 210
    0000040 302 200 342 007 200 302 060 315 041 303
    0000052

I was able to enter it successfully with the octal input program on
the second try.  (I was hitting Return after each line to make the
screen match the listing of numbers, and the first time, I forgot to
hit space at the end of the second line, resulting in a missing byte.)
It does more or less work, but there’s a silly bug: because I’m doing
the zero test on the input parameter instead of the parameter for the
candidate recursion, every number is printed with a leading 0: 0271 01
01 0264 01 0315 etc.  Fixing that problem wouldn’t make the program
any longer, but I am not going to bother at the moment.

A minimal screen editor: 78 bytes?
----------------------------------

The most straightforward editor program would load a file into the
screen buffer (alternate bytes starting typically at b800:0000), let
you move your cursor around and type characters onto it, and then
write the screen contents to an output file upon exit.

A screen editor working on these principles might look something like
this (78 bytes, untested and probably buggy):

            .code16
            .org 0x100
            mov $0xb8, %ah
            mov %ax, %ds
            mov %ax, %es

            xor %di, %di
            mov $2000, %cx
    rdloop: mov $0x01, %ah
            int $0x21
            inc %di
            stosb
            loop rdloop

            xor %di, %di
    edit:   mov $0x06, %ah
            mov $0xff, %dl
            int $0x21
            jz edit                 # if no char available
            cmp $32, %al
            jz forward
            cmp $8, %al
            jz back
            cmp $27, %al
            jz done

            ## otherwise, edit char with octal digit
            mov (%di), %bl
            shl $3, %bl
            and $7, %al
            or %al, %bl
            mov %bl, (%di)
            jmp edit

    forward:
            inc %di
            inc %di
            jmp edit
    back:   dec %di
            dec %di
            jmp edit

    done:   
            mov $2000, %cx
            xor %si, %si
    wrloop: inc %si
            lodsb
            mov %al, %dl
            mov $0x02, %ah
            int $0x21
            loop wrloop
            ret

If this works, it lets you use space and backspace to move around your
(presumably still very small) file on the screen, and type octal
digits to change the characters you see, and when you hit ESC, it
dumps the edited results to standard output, which you have hopefully
redirected to a file.  It doesn’t exactly have a backspace, but you
can overwrite an erroneous character by typing three more digits.
(Which also works with the previous octal-input program.)

My thought is that this program, even without a visible cursor, is
probably enough to bootstrap a more convenient and powerful
programming environment, one with enough of an assembler to be usable.

Conclusion
----------

Using modern tools as cognitive aids (so I didn’t have to
hand-assemble) and to diagnose problems allowed me to do this in a few
hours.  It might have taken a few days in Sean’s scenario.  It
probably helps a lot that I can already more or less write code.

Appendix
--------

Sean’s article linked to the following textphile, which I fished out
of the Internet Archive’s Wayback Machine.  I reproduce it here for
its historical interest, despite its errors and general goofiness.

       Legion2000 Security Research


    iqlord writes: When you can master this you won't need any tools to do your
    preprocessing, compiling, assembling or linking. Because you have then reached
    the bottom, and you will be doing it all by yourself.
    You will have total control!

    Enjoy!


    ;
    ; Legion2000 SR iqlord's eXtreme coding
    ;
    ;        ____  ___ __
    ;   ____ \   \/  //  |________   ____   _____   ____
    ; _/ __ \ \     /\   __\_  __ \_/ __ \ /     \_/ __ \
    ; \  ___/ /     \ |  |  |  | \/\  ___/|  Y Y  \  ___/
    ;  \___  >___/\  \|__|  |__|    \___  >__|_|  /\___  >
    ;      \/      \_/                  \/      \/     \/
    ;                                   .___.__
    ;                    ____  ____   __| _/|__| ____    ____
    ;                  _/ ___\/  _ \ / __ | |  |/    \  / ___\
    ;                  \  \__(  <_> ) /_/ | |  |   |  \/ /_/  >
    ;                   \___  >____/\____ | |__|___|  /\___  /
    ;                       \/           \/         \//_____/
    ;
    ; For experienced thirsty hackers only!
    ; - File is ANSI and not UNICODE
    ; - Todays smooches goes to rattlesnake, ntfx and ultra-m
    ;
    ; Enjoy!
    ;

    __Howto_______________________________________________________
    \____________________________________________________________/

       To write and save the input without using an external
       editor you can use CON.
       CON (Console) is (keyb for input) and (monitor for output).

       copy CON filename.ext

       This will place the input in a buffer.
       To save the buffer and create a file you press CTRL-Z.

       Ex:
       copy CON file.com   -> set buffer
       ALT-195             -> code
       CTRL-Z              -> write buffer to file.com

    __Ex.1_[1Byte]________________________________________________
    \____________________________________________________________/

       Purpose
       --------
       This program will simply return (nothing).

       Code string
       ------------
       ALT-195, CTRL-Z

       Disassembled code
       ------------------
       :0001.0100 C3                     retn

    __Ex.2_[4Byte]________________________________________________
    \____________________________________________________________/

       Purpose
       --------
       This program will exit in a proper way.

       Code string
       ------------
       ALT-180, ALT-76, ALT-205, ALT-33, CTRL-Z

       Disassembled code
       ------------------
       :0001.0100 B44C                   mov ah, 4C
       :0001.0102 CD21                   int 21

    __Ex.3_[10Byte]_______________________________________________
    \____________________________________________________________/

       Purpose
       --------
       This program will halt and wait for a keypress and then
       exit in a proper way.

       Code string
       ------------
       ALT-180, ALT-09, ALT-254, ALT-204, ALT-205, ALT-33,
       ALT-180, ALT-76, ALT-205, ALT-33, CTRL-Z

       Disassembled code
       ------------------
       :0001.0100 B409                   mov ah, 09
       :0001.0102 FECC                   dec ah
       :0001.0104 CD21                   int 21
       :0001.0106 B44C                   mov ah, 4C
       :0001.0108 CD21                   int 21

    __Ex.4_[24Byte_(string_size_included)]________________________
    \____________________________________________________________/

       Purpose
       --------
       This program will print out a string and then return.

       Code string
       ------------
       ALT-186, ALT-09, ALT-01, ALT-180, ALT-09, ALT-205,
       ALT-33, ALT-195, ALT 32, Extreme Coding$, CTRL-Z

       Disassembled code
       ------------------
       :0001.0100 BA0901                 mov dx, 0109
       :0001.0103 B409                   mov ah, 09
       :0001.0105 CD21                   int 21
       :0001.0107 C3                     retn

       :0001.0108 204578                 and [di+78], al
       :0001.010B 7472                   je 017F
       :0001.010D 65                     BYTE 065h

       :0001.010E 6D                     insw
       :0001.010F 6520436F               and gs:[bp+di+6F], al
       :0001.0113 64696E672400           imul bp, fs:[bp+67], 0024

    __dec____________asm_________________________hex______________
    \____________________________________________________________/

       ALT-00      -> add [bx][si],al          -> (00) # N/A
       ALT-01      -> add [bx][si],ax          -> (01)
       ALT-02      -> add al,[bx][si]          -> (02)
       ALT-03      -> add ax,[bx][si]          -> (03)
       ALT-04      -> add al,000               -> (04)
       ALT-05      -> add ax,00000             -> (05)

       ALT-06      -> push es                  -> (06)
       ALT-07      -> pop es                   -> (07)

       ALT-08      -> or [bx][si],al           -> (08) # N/A
       ALT-09      -> or [bx][si],ax           -> (09)
       ALT-10      -> or al,[bx][si]           -> (0A)
       ALT-11      -> or ax,[bx][si]           -> (0B)
       ALT-12      -> or al,000                -> (0C)
       ALT-13      -> or ax,00000              -> (0D) # N/A

       ALT-14      -> push cs                  -> (0E)
       ALT-15      -> sldt [bx][si]            -> (0F)

       ALT-16      -> adc [bx][si],al          -> (10)
       ALT-17      -> adc [bx][si],ax          -> (11)
       ALT-18      -> adc al,[bx][si]          -> (12)
       ALT-19      -> adc ax,[bx][si]          -> (13)
       ALT-20      -> adc al,000               -> (14)
       ALT-21      -> adc ax,00000             -> (15)

       ALT-22      -> push ss                  -> (16)
       ALT-23      -> pop ss                   -> (17)

       ALT-24      -> sbb [bx][si],al          -> (18)
       ALT-25      -> sbb [bx][si],ax          -> (19)

       ALT-26      -> al,[bx][si]              -> (1A) # N/A
       ALT-27      -> ax,[bx][si]              -> (1B)

       ALT-28      -> sbb al,000               -> (1C)
       ALT-29      -> sbb ax,00000             -> (1D)

       ALT-30      -> push ds                  -> (1E)
       ALT-31      -> pop ds                   -> (1F)

       ALT-32      -> and [bx][si],al          -> (20)
       ALT-33      -> and [bx][si],ax          -> (21)
       ALT-34      -> and al,[bx][si]          -> (22)
       ALT-35      -> and ax,[bx][si]          -> (23)
       ALT-36      -> and al,000               -> (24)
       ALT-37      -> and ax,00000             -> (25)

       ALT-38      -> add es:[bx][si],al       -> (26)
       ALT-39      -> daa                      -> (27)

       ALT-40      -> sub [bx][si],al          -> (28)
       ALT-41      -> sub [bx][si],ax          -> (29)

       ALT-42      -> al,[bx][si]              -> (2A)
       ALT-43      -> ax,[bx][si]              -> (2B)

       ALT-44      -> sub al,000               -> (2C)
       ALT-45      -> sub ax,00000             -> (2D)

       ALT-46      -> add cs:[bx][si],al       -> (2E)
       ALT-47      -> das                      -> (2F)

       ALT-48      -> xor [bx][si],al          -> (30)
       ALT-49      -> xor [bx][si],ax          -> (31)
       ALT-50      -> xor al,[bx][si]          -> (32)
       ALT-51      -> xor ax,[bx][si]          -> (33)
       ALT-52      -> xor al,000               -> (34)
       ALT-53      -> xor ax,00000             -> (35)

       ALT-54      -> add ss:[bx][si],al       -> (36)
       ALT-55      -> aaa                      -> (37)

       ALT-56      -> cmp [bx][si],al          -> (38)
       ALT-57      -> cmp [bx][si],ax          -> (39)
       ALT-58      -> cmp al,[bx][si]          -> (3A)
       ALT-59      -> cmp ax,[bx][si]          -> (3B)
       ALT-60      -> cmp al,000               -> (3C)
       ALT-61      -> cmp ax,00000             -> (3D)

       ALT-62      -> add ds:[bx][si],al       -> (3E)
       ALT-63      -> aas                      -> (3F)

       ALT-64      -> inc ax                   -> (40) # COMMON
       ALT-65      -> inc cx                   -> (41) # COMMON
       ALT-66      -> inc dx                   -> (42)
       ALT-67      -> inc bx                   -> (43)
       ALT-68      -> inc sp                   -> (44)
       ALT-69      -> inc bp                   -> (45)
       ALT-70      -> inc si                   -> (46)
       ALT-71      -> inc di                   -> (47)

       ALT-72      -> dec ax                   -> (48) # COMMON
       ALT-73      -> dec cx                   -> (49) # COMMON
       ALT-74      -> dec dx                   -> (4A)
       ALT-75      -> dec bx                   -> (4B)
       ALT-76      -> dec sp                   -> (4C)
       ALT-77      -> dec bp                   -> (4D)
       ALT-78      -> dec si                   -> (4E)
       ALT-79      -> dec di                   -> (4F)

       ALT-80      -> push ax                  -> (50)
       ALT-81      -> push cx                  -> (51)
       ALT-82      -> push dx                  -> (52)
       ALT-83      -> push bx                  -> (53)
       ALT-84      -> push sp                  -> (54)
       ALT-85      -> push bp                  -> (55)
       ALT-86      -> push si                  -> (56)
       ALT-87      -> push di                  -> (57)

       ALT-88      -> pop ax                   -> (58)
       ALT-89      -> pop cx                   -> (59)
       ALT-90      -> pop dx                   -> (5A)
       ALT-91      -> pop bx                   -> (5B)
       ALT-92      -> pop sp                   -> (5C)
       ALT-93      -> pop bp                   -> (5D)
       ALT-94      -> pop si                   -> (5E)
       ALT-95      -> pop di                   -> (5F)

       ALT-96      -> pusha                    -> (60)
       ALT-97      -> popa                     -> (61)
       ALT-98      -> bound ax,[bx][si]        -> (62)
       ALT-99      -> arpl [bx][si],ax         -> (63)

       ALT-100     -> add fs:[bx][si],al       -> (64)
       ALT-101     -> add gs:[bx][si],al       -> (65)
       ALT-102     -> add [bx][si],al          -> (66)
       ALT-103     -> add [eax],al             -> (67)

       ALT-104     -> push 00000               -> (68)
       ALT-105     -> imul ax,w,[bx][si],00000 -> (69)
       ALT-106     -> push 000                 -> (6A)
       ALT-107     -> imul ax,w,[bx][si],000   -> (6B)

       ALT-108     -> insb                     -> (6C)
       ALT-109     -> insw                     -> (6D)

       ALT-110     -> outsb                    -> (6E)
       ALT-111     -> outsw                    -> (6F)

       ALT-112     -> jo 000000002             -> (70)
       ALT-113     -> jno 000000002            -> (71)
       ALT-114     -> jb 000000002             -> (72)
       ALT-115     -> jae 000000002            -> (73)
       ALT-116     -> je 000000002             -> (74)
       ALT-117     -> jne 000000002            -> (75)
       ALT-118     -> jbe 000000002            -> (76)
       ALT-119     -> ja 000000002             -> (77)
       ALT-120     -> js 000000002             -> (78)
       ALT-121     -> jns 000000002            -> (79)
       ALT-122     -> jp 000000002             -> (7A)
       ALT-123     -> jnp 000000002            -> (7B)
       ALT-124     -> jl 000000002             -> (7C)
       ALT-125     -> jge 000000002            -> (7D)
       ALT-126     -> jle 000000002            -> (7E)
       ALT-127     -> jg 000000002             -> (7F)

       ALT-128     -> add b,[bx][si],000       -> (80)
       ALT-129     -> add w,[bx][si],00000     -> (81)
       ALT-130     -> add b,[bx][si],000       -> (82)
       ALT-131     -> add w,[bx][si],000       -> (83)

       ALT-132     -> test [bx][si],al         -> (84)
       ALT-133     -> test [bx][si],ax         -> (85)

       ALT-134     -> xchg al,[bx][si]         -> (86)
       ALT-135     -> xchg ax,[bx][si]         -> (87)

       ALT-136     -> mov [bx][si],al          -> (88)
       ALT-137     -> mov [bx][si],ax          -> (89)
       ALT-138     -> mov al,[bx][si]          -> (8A)
       ALT-139     -> mov ax,[bx][si]          -> (8B)
       ALT-140     -> mov [bx][si],es          -> (8C)

       ALT-141     -> lea ax,[bx][si]          -> (8D)
       ALT-142     -> mov es,[bx][si]          -> (8E)
       ALT-143     -> pop w,[bx][si]           -> (8F)

       ALT-144     -> nop                      -> (90) # COMMON

       ALT-145     -> xchg cx,ax               -> (91)
       ALT-146     -> xchg dx,ax               -> (92)
       ALT-147     -> xchg bx,ax               -> (93)
       ALT-148     -> xchg sp,ax               -> (94)
       ALT-149     -> xchg bp,ax               -> (95)
       ALT-150     -> xchg si,ax               -> (96)
       ALT-151     -> xchg di,ax               -> (97)

       ALT-152     -> cbw                      -> (98)
       ALT-153     -> cwd                      -> (99)

       ALT-154     -> call 00000:000000        -> (9A)

       ALT-155     -> fwait                    -> (9B)
       ALT-156     -> pushf                    -> (9C)
       ALT-157     -> popf                     -> (9D)
       ALT-158     -> sahf                     -> (9E)
       ALT-159     -> lahf                     -> (9F)

       ALT-160     -> mov al,[00000]           -> (A0)
       ALT-161     -> mov ax,[00000]           -> (A1)
       ALT-162     -> mov [00000],al           -> (A2)
       ALT-163     -> mov [00000],ax           -> (A3)

       ALT-164     -> movsb                    -> (A4)
       ALT-165     -> movsw                    -> (A5)

       ALT-166     -> cmpsb                    -> (A6)
       ALT-167     -> cmpsw                    -> (A7)

       ALT-168     -> test al,000              -> (A8)
       ALT-169     -> test ax,00000            -> (A9)

       ALT-170     -> stosb                    -> (AA)
       ALT-171     -> stosw                    -> (AB)
       ALT-172     -> lodsb                    -> (AC)
       ALT-173     -> lodsw                    -> (AD)
       ALT-174     -> scasb                    -> (AE)
       ALT-175     -> scasw                    -> (AF)

       ALT-176     -> mov al,000               -> (B0)
       ALT-177     -> mov cl,000               -> (B1)
       ALT-178     -> mov dl,000               -> (B2)
       ALT-179     -> mov bl,000               -> (B3)
       ALT-180     -> mov ah,000               -> (B4)
       ALT-181     -> mov ch,000               -> (B5)
       ALT-182     -> mov dh,000               -> (B6)
       ALT-183     -> mov bh,000               -> (B7)

       ALT-184     -> mov ax,00000             -> (B8)
       ALT-185     -> mov cx,00000             -> (B9)
       ALT-186     -> mov dx,00000             -> (BA)
       ALT-187     -> mov bx,00000             -> (BB)
       ALT-188     -> mov sp,00000             -> (BC)
       ALT-189     -> mov bp,00000             -> (BD)
       ALT-190     -> mov si,00000             -> (BE)
       ALT-191     -> mov di,00000             -> (BF)

       ALT-192     -> rol b,[bx][si],000       -> (C0)
       ALT-193     -> rol w,[bx][si],000       -> (C1)

       ALT-194     -> retn 00000               -> (C2)
       ALT-195     -> retn                     -> (C3) # COMMON

       ALT-196     -> les ax,[bx][si]          -> (C4)
       ALT-197     -> lds ax,[bx][si]          -> (C5)
       ALT-198     -> mov b,[bx][si],000       -> (C6)
       ALT-199     -> mov w,[bx][si],00000     -> (C7)

       ALT-200     -> enter 00000,000          -> (C8)
       ALT-201     -> leave                    -> (C9)

       ALT-202     -> retf,0000                -> (CA)
       ALT-203     -> retf                     -> (CB)

       ALT-204     -> int 3                    -> (CC)
       ALT-205     -> int 000                  -> (CD) # COMMON
       ALT-206     -> into                     -> (CE)
       ALT-207     -> iret                     -> (CF)

       ALT-208     -> rol b,[bx][si],1         -> (D0)
       ALT-209     -> rol w,[bx][si],1         -> (D1)
       ALT-210     -> rol b,[bx][si],cl        -> (D2)

       ALT-211     -> rol w,[bx][si],cl        -> (D3)

       ALT-212     -> aam 000                  -> (D4)
       ALT-213     -> aad 000                  -> (D5)

       ALT-214     -> setalc                   -> (D6)
       ALT-215     -> xlat                     -> (D7)

       ALT-216     -> fadd d,[bx][si]          -> (D8)
       ALT-217     -> fld d,[bx][si]           -> (D9)
       ALT-218     -> fiadd d,[bx][si]         -> (DA)
       ALT-219     -> fild d,[bx][si]          -> (DB)

       ALT-220     -> fadd q,[bx][si]          -> (DC)
       ALT-221     -> fld q,[bx][si]           -> (DD)
       ALT-222     -> fiadd w,[bx][si]         -> (DE)
       ALT-223     -> fild w,[bx][si]          -> (DF)

       ALT-224     -> loopne 000000002         -> (E0)
       ALT-225     -> loope 000000002          -> (E1)
       ALT-226     -> loop 000000002           -> (E2)
       ALT-227     -> jcxz 000000002           -> (E3)

       ALT-228     -> in al,000                -> (E4)
       ALT-229     -> in ax,000                -> (E5)

       ALT-230     -> out 000,al               -> (E6)
       ALT-231     -> out 000,ax               -> (E7)

       ALT-232     -> call 000000003           -> (E8)
       ALT-233     -> jmp 000000003            -> (E9)

       ALT-234     -> jmp 00000:00000          -> (EA)
       ALT-235     -> jmps 000000002           -> (EB)

       ALT-236     -> in al,dx                 -> (EC)
       ALT-237     -> in ax,ax                 -> (ED)

       ALT-238     -> out dx,al                -> (EE)
       ALT-239     -> out dx,ax                -> (EF)

       ALT-240     -> lock                     -> (F0)
       ALT-241     -> ???                      -> (F1)
       ALT-242     -> repne                    -> (F2)
       ALT-243     -> repe                     -> (F3)
       ALT-244     -> hlt                      -> (F4)
       ALT-245     -> cmc                      -> (F5)

       ALT-246     -> test b,[bx][si],000      -> (F6)
       ALT-247     -> test w,[bx][si],00000    -> (F7)

       ALT-248     -> clc                      -> (F8)
       ALT-249     -> stc                      -> (F9)
       ALT-250     -> cli                      -> (FA)
       ALT-251     -> sti                      -> (FB)
       ALT-252     -> cld                      -> (FC)
       ALT-253     -> std                      -> (FD)

       ALT-254     -> inc b,[bx][si]           -> (FE)
       ALT-255     -> inc w,[bx][si]           -> (FF)

    __none_useable_code___________________________________________
    \____________________________________________________________/

       ALT-00      -> add [bx][si],al          -> (01)
       ALT-08      -> or [bx][si],al           -> (08)
       ALT-13      -> or ax,00000              -> (0D)
       ALT-26      -> al,[bx][si]              -> (1A) = ^Z

       0,3,6,8,16(0x10),19(0x13),27(0x1b),255(0xFF)

    __combinations________________________________________________
    \____________________________________________________________/

       ALT-180 + ALT-76   -> mov ah,4Ch        -> (B44C) # COMMON
       ALT-205 + ALT-33   -> int 21h           -> (CD21) # COMMON
       ALT-254 + ALT-196  -> inc ah            -> (FEC4)
       ALT-254 + ALT-204  -> dec ah            -> (FECC)

       /iqlord : l2k SR : respect to ya all!


More information about the Kragen-hacks mailing list