nedoPC.org

Electronics hobbyists community established in 2002
Atom Feed | View unanswered posts | View active topics It is currently 28 Mar 2024 03:46



Reply to topic  [ 14 posts ] 
[ASM] Worm 
Author Message
Doomed

Joined: 16 Mar 2002 17:00
Posts: 490
Reply with quote
Нет, к вирусам и троянам эта тема отношения не имеет;) Сабж - это моя попытка (двухлетней с небольшим давности) написать всем известную игрушку Piton на x86 ассемблере, сделав её как можно меньше. Долгое время не мог уложить её менее, чем в 189 байт; весной прошлого года по совету товарища E}|{ укоротил её ещё на пару байт. На том пока и застрял;)

Кто хочет поразвлечься, попытавшись сделать код ещё короче - ниже привожу исходник. Работает на 086, в текстовом режиме (вывод атрибутами текста). Нормально запускается под Win XP, скорость игры не изменяется на любом компе.

Code:
; Worm-187 by Shiru Otaku^IIpr 23.03.2005
; это просто игрушка Питон размером в 187 байт

CODESG SEGMENT BYTE 'CODE'
       ASSUME CS:CODESG, DS:CODESG, SS:CODESG, ES:CODESG
       ORG    100H


MAIN   PROC   NEAR

      mov es,ax
      int 10h

      mov bh,0b8h
      mov ds,bx
      
gameStart:
      mov bh,09h
clearAttr:
      mov byte ptr[bx],011h
      dec bx
      jnz clearAttr

      mov bl,0a6h
fillFld0:
      mov cl,044h
fillFld1:
      mov byte ptr[bx],ch
      inc bx
      loop fillFld1
      add bx,12
      cmp bh,07h
      jb fillFld0

      mov bx,1000h
      mov dx,4
      inc si
      inc si
      mov cl,dl
initWorm:
      mov word ptr[bx],03e5h
      add bx,si
      loop initWorm

genPiece:

randSeed=$+1
      mov bx,0
        add bx,word ptr es:[046ch]
        and bh,07h
        mov word ptr cs:[randSeed],bx
      or bl,1
        cmp cl,byte ptr[bx]
        jne genPiece
       mov byte ptr[bx],0bbh

gameLoop:

      mov cl,2
waitLoop0:
      mov al,byte ptr es:[046ch]
waitLoop1:
      cmp al,byte ptr es:[046ch]
      je waitLoop1
      loop waitLoop0
      
      mov ah,ch
      mov cx,dx
      mov bx,0ffeh

drawWorm:
      inc bx
      inc bx
      mov di,word ptr[bx]
      mov word ptr[bx-2],di
      mov byte ptr[di],ah
      mov ah,0aah
      loop drawWorm
      
      cmp si,cx
      je gameStart
      
      mov ah,1
      int 16h
      jz inpTest3
      xor ah,ah
       int 16h
      
      mov al,ah
       cmp al,48h
       jne inpTest0
       mov si,0ffb0h
inpTest0:
         cmp al,50h
         jne inpTest1
         mov si,50h
inpTest1:
      cmp al,4bh
      jne inpTest2
      mov si,0fffeh
inpTest2:
      cmp al,4dh
      jne inpTest3
      mov si,2
inpTest3:

      add di,si
      mov word ptr[bx],di
      mov word ptr[bx+2],di

      mov al,byte ptr[di]
      cmp al,cl
      je inpTest4
      inc dx
      cmp al,0bbh
      je genPiece
      mov si,cx
inpTest4:
       cmp ah,1
       jne gameLoop

      mov ax,3
      int 10h

      ret
      
MAIN   ENDP
CODESG ENDS
       END  MAIN


Ещё раньше аналогичная попытка предпринималась мною на Speccy, но там я сделал игрушку в 255 байт, со звуковыми эффектами и прочей ерундой - чтобы максимально забить 1 сектор;)

А началась эта история с желания написать питона размером в 128 байт. Пока мне это не удалось ни на одной платформе;)


19 Jan 2006 19:01
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
Смотри ка ты - работает :)

Image

Во истину - NedoPC ;)

Кто не верит что оно действительно 187 байт занимает - качайте и смотрите сами: WORM.COM

_________________
:dj: https://mastodon.social/@Shaos


Last edited by Shaos on 21 Jan 2006 08:34, edited 1 time in total.



20 Jan 2006 21:13
Profile WWW
Senior

Joined: 07 Aug 2006 10:18
Posts: 185
Reply with quote
Post 
этт... а что делает `int 0x16' с ah, в случае если нету ввода? я из dosemu пытался погонять -- дык, условный переход:
Code:
inpTest4:
       cmp ah,1
       jne gameLoop

не выполняется нифига. Если нечего читать, dosemu'шный бивис не трогает ah, ограничиваясь установкой zf. а что делает "настоящий"?
я в раздумьях кого править: worm.com или dosemu :)


07 Aug 2006 10:27
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
bar wrote:
этт... а что делает `int 0x16' с ah, в случае если нету ввода? я из dosemu пытался погонять -- дык, условный переход:
Code:
inpTest4:
       cmp ah,1
       jne gameLoop

не выполняется нифига. Если нечего читать, dosemu'шный бивис не трогает ah, ограничиваясь установкой zf. а что делает "настоящий"?
я в раздумьях кого править: worm.com или dosemu :)


DOSBox эмулит всё как надо (см. скриншот) - переходи на него ;)

_________________
:dj: https://mastodon.social/@Shaos


07 Aug 2006 16:39
Profile WWW
Senior

Joined: 07 Aug 2006 10:18
Posts: 185
Reply with quote
Post 
в dosemu добавил обнуление ah -- оно заработало, но кривовато: у dosemu проблемы с видеорежимом 0. в консоли вообще не хочет, а в X'ах, может если шрифт подходящий подобрать, то будет в самый раз.
Shaos wrote:
DOSBox эмулит всё как надо (см. скриншот) - переходи на него ;)

:)
поставил я его...
та же фигня. Даже скачал приведённый worm.com: думаю мало ли что. dosbox'овый биос тоже не меняет значение ah. Обнуляю ah -- работает, прям как на скриншоте.
:roll: А у тебя "чистый" dosbox 0.63? В смысле нету ли на нём левых патчей от debian, rh или ещё откуда?


07 Aug 2006 19:59
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
bar wrote:
в dosemu добавил обнуление ah -- оно заработало, но кривовато: у dosemu проблемы с видеорежимом 0. в консоли вообще не хочет, а в X'ах, может если шрифт подходящий подобрать, то будет в самый раз.
Shaos wrote:
DOSBox эмулит всё как надо (см. скриншот) - переходи на него ;)

:)
поставил я его...
та же фигня. Даже скачал приведённый worm.com: думаю мало ли что. dosbox'овый биос тоже не меняет значение ah. Обнуляю ah -- работает, прям как на скриншоте.
:roll: А у тебя "чистый" dosbox 0.63? В смысле нету ли на нём левых патчей от debian, rh или ещё откуда?


Чистый DOSBox под линух - скачанный с ихнего сайта

А где ты AH обнуляешь? Там же есть XOR AH,AH - обнуление. А проверка на 1 похоже на ESC.

_________________
:dj: https://mastodon.social/@Shaos


08 Aug 2006 04:49
Profile WWW
Senior

Joined: 07 Aug 2006 10:18
Posts: 185
Reply with quote
Post 
Code:
    mov ah, 1 ;запихнули в ah 1
    int 16h
    jz inpTest3
[...]
inpTest3:
[...] ; ничего влияющего на значение ah
      ; отсюда можно уйти не на inpTest4, но только если сожрать кролика
    cmp ah, 1 ;и если ввода небыло, то ah до сих пор 1.
              ;запихивали номер функции, а теперь трактуем как
              ;скан-код клавиши
    jne gameLoop

если в фции 1 int 16 обнулить ah, то работает, даже если ввода нет.
Либо можно обнулить после int16 по значению ZF.

DOSBox, говоришь чистый... у меня, по ходу дела, тоже. патчи которые ебилд накладывает, к делу никакого отношения не имеют. обновил dosbox до 0.65 -- тоже не работает.
Странно всё это... Заглянул в сорец dosbox'а -- там, вроде как, gcc не может оказать своего пагубного влияния на ah. фихня какая-то. И чем дальше, тем больше я сомневаюсь в правильности обнуления ah в int16.

ps. но dosbox это бонус :) на нём в супаплекс можно играть -- в dosemu мне так и не удалось скорость настроить.


08 Aug 2006 06:29
Profile
Senior

Joined: 07 Aug 2006 10:18
Posts: 185
Reply with quote
Post 
однако, award'овый биос, по ходу дела, изменяет значение ah. нифига не понимаю, как оно могло работать на dosbox в неизменном виде.


08 Aug 2006 07:03
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
Ну у меня dosbox-0.63, собранный из исходников и запускаемый через dboxfe-0.0.5, также из исходников полученный. Всё работает - только что проверил. WORM.COM собран функциональным аналогом MASM-a (называется Arrowsoft Assembler - публик домайн) в том же DOSBox-e.

Посмотрел код - AH там при ненажатой кнопке не меняется...

Проверил экспериментально - после mov ah,1 и int 16h при ненажатой кнопке в AH сидит #11, значит всё-таки меняется...

_________________
:dj: https://mastodon.social/@Shaos


08 Aug 2006 17:24
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
Shaos wrote:
Посмотрел код - AH там при ненажатой кнопке не меняется...

Проверил экспериментально - после mov ah,1 и int 16h при ненажатой кнопке в AH сидит #11, значит всё-таки меняется...


Ооо - там не зря стоит обработчик двух случаев - case 0x01 и case 0x11 - хотя я так и не нашёл то место, где 0x01 превращается в 0x11...

_________________
:dj: https://mastodon.social/@Shaos


08 Aug 2006 18:29
Profile WWW
Senior

Joined: 07 Aug 2006 10:18
Posts: 185
Reply with quote
Post 
Shaos wrote:
Проверил экспериментально - после mov ah,1 и int 16h при ненажатой кнопке в AH сидит #11, значит всё-таки меняется...

я тоже экспериментально. у меня не меняется и хоть тресни. ладно, я в обработчике int16 dosbox'а тоже обнулил ah.


09 Aug 2006 03:51
Profile
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
Новый рекорд:

Code:
;Worm-154 by Shelwien 19.11.2006
;http://compression.ru/sh

CODESG SEGMENT BYTE 'CODE'
       ASSUME CS:CODESG, DS:CODESG, SS:CODESG, ES:CODESG
       ORG    100H

ideal
p286

MAIN:
; ax = temp
; bx = snake head ptr
; cx = temp
; dx = temp (mostly unused)
; si = temp (mostly unused)
; di = video ptr
; bp = unused ; random seed
; es = b800

;buf = 736h-4*2
buf = 03E5h-4*2

;      pop   fs
      int 16

;      mov bh,0b8h
;      mov es,bx

      xchg   di,ax
      mov   al,11h
      ;xor   di,di
;      mov   ch,high 900h
      mov   cx,0b800h
      mov   es,cx
   rep   stosb
      xchg   cx,ax

gameStart:    ; ax=0 at start and after jump
;      mov   al,0
;      mov   di,(40*2+3)*2
;f0:      mov   cx,(40-3*2)
;   rep   stosw
;      add   di,3*2*2
;      cmp   di,700h
;      jb   f0

      mov   cx,21
      mov   di,(40*2+3)*2
f0:      push   cx
      mov   cl,(40-3*2)
   rep   stosw
      pop   cx
      add   di,3*2*2
      loop   f0

;      mov   ax,(12*40+18)*2+1 ; 03E5h
;      mov   bx,buf+4*2
;      mov   bx,di
;      mov   sp,bx
;      push   ax ax ax ax

      mov   bx,buf+4*2
      mov   sp,bx
      push   bx bx bx bx
      
      test   ax,?
      org $-2   

genPiece:    inc   bx   ; len increment
      inc   bx

gp1:      ;add   bp,[word fs:046ch]
      xor   ax,ax   ; ah=0 on all pathes, but int 1ah spoils all the fun
      int 26
;      add   bp,dx
      
      add   di,dx
      and   di,07FEh

;      xor   ax,ax
      scasw
      jnz   gp1
      dec   di
      mov   al,0bbh
      stosb

gameLoop:


;      mov   si,046ch
;      mov   ax,[word fs:si]
;      add   ax,2
;w0:      cmp   ax,[word fs:si]
;      jnz   w0

      mov   ah,0
      int 26
      mov   si,dx
      inc   si
      inc   si
w0:      ;mov   ah,0
      int 26
      cmp   dx,si
      jnz   w0
      
      mov   ah,1
      int 22
      jz   inpTest3
      mov   ah,0
      int 22
 
      cmp   al,27 ; esc ascii
      jz   quit

      xchg   dx,ax   
inpTest3:    
      mov   si,offset cmds
i0:      lodsw
      cmp   ah,dh
      jnz   i1
      mov   [byte ds:MoveDir],al
i1:      test   ax,ax
      jnz   i0

;      mov   si,offset cmds
;i0:      lods   [byte ds:si]
;      cmp   al,ah
;      lods   [byte ds:si]
;      jz   i1
;      cmp   al,0
;      jnz   i0
;i1:      ;cbw
;      ;xchg   dx,ax
;      mov   [byte ds:MoveDir],al

;      mov   al,0
dw0:      pop   di
      push   di di
      pop   di
      stosb
      pop   di
      mov   al,0aah
      cmp   sp,bx
      jb   dw0
      
;      add   di,dx
      add   di,2
      MoveDir = $-1
      pop   ax
      push   di di

      mov   sp,buf

      mov   al,0bbh
      scasb   
      jz   genPiece
      dec   di ; it was attr already
      xor   ax,ax
      scasb
      je   gameLoop
      jmp   gameStart

quit:      mov   ax,3
      int 16
      int 32

cmds:
;      db   48h,-50h
;      db   50h, 50h
;      db   4bh,-02h
;      db   4dh, 02h
;      db     0,   0
      
      db   -50h,48h
      db    50h,50h
      db   -02h,4bh
      db    02h,4dh
      db      0,  0
      
ENDS
END  MAIN



Для сборки нужен TASM - стандартный MASM на этот код будет ругаться

_________________
:dj: https://mastodon.social/@Shaos


06 Dec 2006 23:02
Profile WWW
Admin
User avatar

Joined: 08 Jan 2003 23:22
Posts: 22409
Location: Silicon Valley
Reply with quote
Post 
Worm для ZX перенёс в другое место

_________________
:dj: https://mastodon.social/@Shaos


06 Sep 2007 14:51
Profile WWW
Junior
User avatar

Joined: 11 Sep 2007 03:54
Posts: 1
Location: Великий Новгород
Reply with quote
Post 
В 97-ом году у нас олимпиада была в универе, надо было написать самого короткого питона. На самой олимпиаде я писал на паскале (правда от паскаля там в итоге остался только begin/end и пара циклов, остальное было встроенный асм)
После я, обложившись справочниками, сваял питона на 117 байт. ;) Правда он был сильно упрощён. Мог уползать влево-вправо и выползал на строку ниже-выше.
Более честная версия занимала 144 байта.
Правда сейчас под XP они не запустились. То-ли что-то с видеопамятью (я просто из фара пробовал запускать), то-ли дело в 15h прерывании которым я задержку делал.
Под DOS 6.0 в те времена работал нормально (и без дос-а, мы его пробовали в бут-сектор дискеты записывать и загружаться с неё ;))

Асм я тогда плохо знал (а сейчас ещё и забыл ;)), поэтому откомментирован практически построчно.
Компилировалось это всё TASM-ом (из состава BC 3.1/BP 7.0)

Самый короткий и слегка нечестный вариант. 117 байт
Code:
; 1997 Eugene Nikulin (LazyBear)


Field_Char   EQU ' '              ; Символ заполнения поля
Field_ChAt   EQU 0F2Eh             
Piton_Char   EQU '█'              ; Символ тела питона
Rabbit_Char  EQU 'K'              ; Символ кролика

 Code segment

  org 100h
  assume cs:CODE,ds:CODE,es:CODE

START:

    xor  AX, AX
    int  10h

    mov  BX, 0B800h                    ; Установить DS на видеопамять
    mov  DS, BX

    mov  BH, 08h                       ; Начальное смещение головы
    mov  DI, BX                        ; Начальное смещение хвоста

    mov  DX, 2                         ; Начальное направление движения
    mov  CX, DX

NEW_RABBIT:

 @11:
    inc  BP   
    mov  SI, [BP]                      ; В SI случайное число
    and  SI, 03FEh                     ; Обрезаем чтобы влезло на экран
    cmp  BYTE ptr [SI], Field_Char     ; Это место пустое?
    jnz  @11                           ; Место не пустое, ищем еще
    mov  BYTE ptr [SI], Rabbit_Char    ; Нарисовать кролика

GAME_LOOP:


    mov  SI, [BX]                      ; В SI координата головы
    mov  BYTE ptr [SI], Piton_Char     ; Нарисовать голову

    add  SI, DX                        ; Добавить смещение
    add  BL, CL                        ; Увеличить указатель головы
    mov  [BX], SI                      ; Записать новое положение головы

    cmp  BYTE ptr [SI], Rabbit_Char    ; Проверка на съедание кролика
    jz   NEW_RABBIT                    ; Кролик съеден!

    cmp  BYTE ptr [SI], Field_Char     ; Проверка на попадание в поле
    jnz  END_GAME                      ; В поле не попали
   

    push DX                            ; Задержка через 15h прерывание
    xor  DX, DX                        ; Задержка на 020000h мс
    mov  AH, 86h
    int  15h
    pop  DX

    xchg DI, BX                        ; В BX указатель на хвост
    mov  SI, [BX]                      ; В SI координата хвоста
    mov  BYTE ptr [SI], Field_Char     ; Затереть хвост
    add  BL, CL                        ; Увеличение указателя на хвост
    xchg DI, BX

    mov  AH, 01                        ; Проверка на нажатую клавишу
    int  16h                           ; В AX код клавиши
    je   GAME_LOOP                     ; Клавиша не нажата

    xchg AH, AL                        ; 'cmp AL' занимает меньше места
                                       ; чем  'cmp AH' !

    cmp  AL, 4Bh                       ; Клавиша влево?
    jnz  @1
    mov  DX, -2
  @1:
    cmp  AL, 4Dh                       ; Клавиша вправо?
    jnz  @2
    mov  DX, CX                        ; CX = 2
  @2:
    cmp  AL, 50h                       ; Клавиша ввниз?
    jnz  @3
    mov  DX, AX                        ; AX = 50h = 80
  @3:
    cmp  AL, 48h                       ; Клавиша вверх?
    jnz  @4
    mov  DX, -80
  @4:
    xor  AH, AH                       
    int  16h                           ; Очистка буфера клавиатуры

    cmp  AL, 27                        ; Проверка на 'Esc'
    jnz GAME_LOOP

END_GAME:
    ret

Code ends
end start


Более честный и цветной. 144 байта
Code:
; 1997 Eugene Nikulin (LazyBear)

Field_Char   EQU 2Eh            ; Символ заполнения поля
Field_ChAt   EQU 0F2Eh             
Piton_Char   EQU 0DBh           ; Символ тела питона
Piton_ChAt   EQU 0ADBh
Rabbit_Char  EQU 4Bh            ; Символ кролика
Rabbit_ChAt  EQU 0C4Bh

Field_Width  EQU 35
Field_Height EQU 20

 Code segment

  org 100h
  assume cs:CODE,ds:CODE,es:CODE

START:

    xor  AX, AX
    int  10h

    mov  BX, 0B800h                    ; Установить DS на видеопамять
    mov  DS, BX

    mov  ES, BX
    xor  DI, DI

    mov  DX, Field_Height
    mov  AX, Field_ChAt
  @15:
    mov  CX, Field_Width
    rep  stosw
    add  DI, 10
    dec  DX
    jnz  @15

    mov  BH, 08h                       ; Начальное смещение головы
    mov  [BX], 810                     ; Начальная координата головы
    mov  DI, BX                        ; Начальное смещение хвоста

    mov  DL, 2                         ; Начальное направление движения
    mov  CX, DX

NEW_RABBIT:

 @11:
    inc  BP
    mov  SI, [BP]                      ; В SI случайное число
    cmp  BYTE ptr [SI], Field_Char     ; Это место пустое?
    jnz  NEW_RABBIT                    ; Место не пустое, ищем еще
    mov  BYTE ptr [SI], Rabbit_Char    ; Нарисовать кролика

GAME_LOOP:


    mov  SI, [BX]                      ; В SI координата головы
    mov  BYTE ptr [SI], Piton_Char     ; Нарисовать голову

    add  SI, DX                        ; Добавить смещение
    add  BL, CL                        ; Увеличить указатель головы
    mov  [BX], SI                      ; Записать новое положение головы

    cmp  BYTE ptr [SI], Rabbit_Char    ; Проверка на съедание кролика
    jz   NEW_RABBIT                    ; Кролик съеден!

    cmp  BYTE ptr [SI], Field_Char     ; Проверка на попадание в поле
    jnz  END_GAME                      ; В поле не попали
   

    push DX                            ; Задержка через 15h прерывание
    xor  DX, DX                        ; Задержка на 020000h мс
    mov  AH, 86h
    int  15h
    pop  DX

    xchg DI, BX                        ; В BX указатель на хвост
    mov  SI, [BX]                      ; В SI координата хвоста
    mov  BYTE ptr [SI], Field_Char     ; Затереть хвост
    add  BL, CL                        ; Увеличение указателя на хвост
    xchg DI, BX

    mov  AH, 01                        ; Проверка на нажатую клавишу
    int  16h                           ; В AX код клавиши
    je   GAME_LOOP                     ; Клавиша не нажата

    xchg AH, AL                        ; 'cmp AL' занимает меньше места
                                       ; чем  'cmp AH' !

    cmp  AL, 4Bh                       ; Клавиша влево?
    jnz  @1
    mov  DX, -2
  @1:
    cmp  AL, 4Dh                       ; Клавиша вправо?
    jnz  @2
    mov  DX, CX                        ; CX = 2
  @2:
    cmp  AL, 50h                       ; Клавиша ввниз?
    jnz  @3
    mov  DX, AX                        ; AX = 50h = 80
  @3:
    cmp  AL, 48h                       ; Клавиша вверх?
    jnz  @4
    mov  DX, -80
  @4:
    xor  AH, AH                       
    int  16h                           ; Очистка буфера клавиатуры

    cmp  AL, 27                        ; Проверка на 'Esc'
    jnz GAME_LOOP

END_GAME:

    mov  AX, 0003h
    int  10h

    ret

Code ends
end start


11 Sep 2007 04:40
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 14 posts ] 

Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.