Graphics Colour Flasher in x86 ASM


Warning: Anyone with epilepsy should avoid creating or running the following program as it may trigger an episode.



Firstly, run a DOS command prompt and load up debug.exe.

c:\> debug.exe
-


At the dash prompt, type:

-a 100

This should give you the ability to code in assembly starting at address 0x100.

Something like this will be seen:

13AB:0100

That consists of segment:offset values. Segment and offset values are what used to be used in MS-DOS (16-bit OS) on the Intel x86, due to the segmented memory structure. The code segment value depends on your system, so it may change and is left out from this tutorial.

Type in the following code:

100: mov ax, 13
103: int 10
105: mov ax, a000
108: mov ds, ax
10a: mov ax, 0
10d: mov bx, 0
110: mov [bx], ax
112: inc bx
113: cmp bx, fa00
117: jne 110
119: inc ax
11a: cmp ax, ff
11d: jne 10d
11f: mov ax, 3
122: int 10
124: int 20

Then type "g" at the dash prompt of debug. You should see the screen flash and change colour, and then exiting.

The idea of the program can be described in the following commented version:

// initialise graphics mode 13h using interrupt service 10h
100: mov ax, 13
103: int 10

// set DATA segment to point to a000, we cannot do this directly, so we use AX register first.
// segment a000 is where VIDEO RAM is memory mapped.
105: mov ax, a000
108: mov ds, ax

// now: fill the screen with a colour, and then when that's done, change the colour.
// this requires a nested loop.
// ax = colour
// bx = screen position
// comments now describe the loop in C pseudocode
// for (ax = 0; ax < 0xff, ax++) {
//    for (bx = 0; bx < 0xfa00; bx++) {
//       char *p = ds:bx;
//       *p = ax;
//    }
// }

// pre-loop ax
10a: mov ax, 0
// pre-loop bx
10d: mov bx, 0

// char *p = ds:bx; *p = ax;
// x86 assumes the use of DS when using [bx] as a pointer.
110: mov [bx], ax

// post-loop bx
112: inc bx
// conditional bx
113: cmp bx, fa00
117: jne 110

// post-loop ax
119: inc ax
// conditional ax
11a: cmp ax, ff
11d: jne 10d

// reset screen back to text mode (mov ax, 3; int 10) and exit program (int 20h)
11f: mov ax, 3
122: int 10
124: int 20


1