Машинный код x86-16 для DOS, 43 байта
; Draw 32x32 red square
B8 0C 28 mov ax, 0x0C28 ; AL == color red, AH == set pixel function
B9 00 1F mov cx, 31
DrawBox:
BA 00 1F mov dx, 31
DrawRow:
CD 10 int 0x10
4A dec dx
75 FB jnz DrawRow
E2 F6 loop DrawBox
; Draw the interior white cross
B0 0F mov al, 0x0F ; high byte already set
B1 06 mov cl, 6 ; high byte already 0
DrawCross:
B2 0D mov dl, 13 ; high byte already 0
DrawCrossInner:
CD 10 int 0x10 ; plot CX, DX
87 D1 xchg dx, cx
CD 10 int 0x10 ; plot DX, CX
87 D1 xchg dx, cx
42 inc dx
80 FA 12 cmp dl, 13+6
75 F2 jne DrawCrossInner
41 inc cx
80 F9 19 cmp cl, 6+(32-6-6)
75 EA jne DrawCross
C3 ret
Приведенный выше код предназначен для сборки в виде файла COM, а затем запускается под DOS. Он вызывает видео сервисы ROM BIOS для построения отдельных пикселей флага, формируя представление швейцарского флага 32 × 32 в верхнем левом углу экрана.
Код предполагает, что режим видео уже установлен в режим 0x13, что также означает, что для него требуется дисплей VGA. Можно использовать другие режимы видео, но при наличии VGA у вас есть две вещи: (1) квадратные пиксели и (2) палитра по умолчанию, которая включает в себя истинный 100% красный ( 0xFF0000
) (то есть вам не нужно тратить байты на изменение палитры цвета). Перед запуском этой программы вам необходимо переключить дисплей в режим 0x13; следующий код - это все, что вам нужно для этого:
mov ax, 0x13
int 0x10
Код не делает никаких других предположений и должен работать на любом x86-совместимом оборудовании под DOS-совместимой операционной системой.
Тем не менее, программа завершает работу сразу после рисования флага, поэтому приглашение DOS обычно будет перепечатываться в верхнем левом углу экрана, закрывая несколько верхних строк флага. Поэтому, если вы хотите удивиться истинному выводу, вам нужно приостановить / приостановить работу системы до того, как она RET
начнет работать. Вот скриншот того, как это выглядит при работе на виртуальной машине FreeDOS:
Возможно, это удастся улучшить, записав пиксельные данные непосредственно в видеобуфер, тем более что я уже использую режим 0x13. Я еще не пробовал это. INT 0x10
это уже довольно короткая инструкция, но если я могу использовать однобайтовые строковые инструкции для записи данных пикселей непосредственно в память, то это может привести к значительной экономии кода.