Отправляет email-рассылки с помощью сервиса Sendsay

Задачи по ассемблеру

  Все выпуски  

Задачи по ассемблеру


Информационный Канал Subscribe.Ru


Задачи по ассемблеру.


Выпуск #16.

Добрый день, уважаемые подписчики! Обновились "Правила" настоятельно прошу с ними ознакомиться. Потому что решения, которые им противоречат приниматься не будут. Нововведение - для лучшей читаемости решений сделал табуляцию.

Сегодня в выпуске:

1. Возвращаясь к задаче #14.

2. Решение задачи #15.

3. Задача #16.

4. NOP - профилактика и методы защиты. Часть II.

5. Команда для COMPO.

6. Дискуссия: новая тема.

Возвращаясь к задаче #14.

Обнаружились ошибки в решениях присланных подписчиками - спасибо другим подписчикам. В общем разбираемся.

Ошибка в решении by Shur. Shur предполагал, что DL=0 при старте программы, а это не так. (Кстати состояние всех регистров при старте программы есть в "Правилах"). Значит, нужно добавить в начало программы xchg ax,dx или cwd для того, чтобы обнулить DX. Значит размер его программы будет 16 байт. 

Ошибка в решении by Broken Sword. Его решение считает "правильной цифрой" все ASCII символы < 31h. Поэтому условие задачи не выполняется.

Эти решения не засчитаны.

Так получилось, что буквально через несколько секунд после того как я послал рассылку ко мне пришло еще два (кстати правильных) решения. Вот они:

Решение by G3 (17 байт):

;Task #14
;tasm /m task.asm
;tlink /x /3 /t task.obj
;17 байт
;by G3
 .model tiny
 .386
 .code
org 100h
Start:
 xchg ax,si  ;присвоить ax=0100h
MainLoop:
 or al,1
 cmp al,31h
 jz L1  ;перейти если al='0' или al='1'
 
 pop dx  ;первый раз присвоить dx=0h, потом dx=00FFh
 push cx
L1:
 int 21h
 cmp al,13
 jnz MainLoop ;перейти если не нажат Enter 
 int 20h
end Start

Решение by Alexey Volkov (18 байт):

; Assembler Tasks COMPO #14
; Способ компиляции: tasm 14.asm, tlink /t 14.obj
; Автор: Alexey Volkov AKA xAL
; Размер: 18 байт
        .model  tiny
        .386
        .code
        org 100h
start:
         xchg     ax, si                ; AX=100h;  AH=01 - номер функции для int21
         cwd                          ; Обнуляем DX
cycle:   int      21h                   ; Чтение символа с клавиатуры в AL
         cmp      al, 0Dh               ; Если "ввод",
         jz       quit                  ; то выходим
         org      $-2                   ; 2х АнтиНОП
        shr      al, 1                 ; -> '0' shr 1 == '1' shr 1 == 18h
         cmp      al, 18h               ; Если (al!=18h), |
         db 0fh,45h,0d1h               ; (cmovnz dx, cx) ^ то DX=00FFh
         jmp      cycle                 ; Продолжаем ввод
quit:    ret
end     start

Решение задачи #14.

Таблица рекордов:

1. Beeblebrox - 21 байт 

2. G3 - 25 байт.

3. Broken Sword - 26 байт.

4. Shur - 26 байт.

5. Alexey_1 - 27 байт.

6. Jendos - 54 байта.

 Условие задачи.

Начертить на экране шахматную доску.

Решения.

Решение by Beeblebrox:

; c15 entry by Beeblebrox / TMA
; 21 bytes
 .model tiny
 .code
 .386
               org      100h
start:      mov      ah,0B8h
                mov      es,ax     ; video seg =0B800h
m0:
                scasw             ; di=0
                mov      cl,8
m1:         xchg     ax,bx     ; char=0, attr=0B8h|0
                stosw
                stosw
                loop     m1
                add      di,160-32-2  ; next row
                xchg     ax,bx
                shl      si,1      ; 8 times
                jnc      m0
                ret
                end      start

 

Комментарий: Это самый короткий из всех присланных кодов.

Идея кода: Используется прямая работа с видеопамятью, заодно старшее слово сегмента видеопамяти используется как атрибут символов "белой" клетки. Процесс рисования клеток по вертикали повторяется 8 раз - и на экране шахматная доска.

 

Решение by G3:

;Task #15
;tasm /m task.asm
;tlink /x /3 /t task.obj
;25 байт
;by G3
 .model tiny
 .386
 .code
org 100h
Start:
     mov bh,0B8h
            mov es,bx  ;es=0B800h
  stosw   ;di=0
            mov al,0DBh  ;код символа в ASCII
            mov cl,8
L1:
  xor ah,[si]  ;установить цвет символа (0h или B7h)
L2:
  stosw   ;вывод ax на экран
  stosw   ;вывод ax на экран
  add bl,32  ;повторить 8 раз (256/32=8)
  jnc L1

  add di,80h  ;перейти к следующей строке
  loop L2

  ret
end Start

 

Комментарий: Идея почти такая же как у Beeblebrx - используется прямая работа с видео памятью, но метод изменения цвета длиннее на 4 байта.

 

Решение by Broken Sword:

; Assembler Tasks COMPO #15
; tasm /m task15.asm
; tlink /x /3 /t task15.obj
; task15.com
; by Broken Sword
; size:  26 bytes

                .model    tiny
                .code
                .386
                org 100h
@@start:
                mov AL,0DBh
                mov BL,8
@@S0:
                mov        CL,8
@@S1:
                int 29h
                int 29h
                xor AL,0FBh
                loop @@S1

                xor AL,0FBh
                mov CL,64
@@S2:
                int 29h
                loop @@S2

                dec          BX
                jnz           @@S0
                ret

                end          @@start

 

Комментарий: Вывод на экран в этом коде осуществляется с помощью int 29h. Сначала выводится закрашенная клетка (0DBh), затем с помощью команды xor al, 0FBh в AL заносится 20h (ASCII-код пробела). С помощью той  команды в AL  возвращается исходное значение. Минус - вместе с клетками выводятся закрашенные строки.

 

Решение by Shur:

;by Shur
        ;26 bytes

 .model tiny
 .code
 .186

        org 100h
start:
        push 0b81fh
        pop es
        mov al,0dbh
        mov cl,8
_row:
        mov bl,8
_cell:
        stosw
        stosw
        xor ah,[si]   ;68h - opcode for push
        dec bx
        jnz _cell

        add di,160-8*2*2
        xor ah,[si]
        loop _row

        ret

 end start

 

Комментарий: Это решение сходно со вторым.

 

Решение by Alexey_1:

;tasm /m2 prog.asm
;tlink /t prog
;27 байт
;by Alex

CSEG segment
assume cs:CSEG, ds:CSEG, ss:CSEG, es:CSEG
org 100h
main:
cwd   ;dx=0, т.к. при загрузке ax=bx=0
mov  ax,02dbh ;  ah=2,номер ф-ции для int 10h, в al код символа
mov  cl,32  ;количество повторов цикла

cicl:
int  29h  ; вывод символа на экран
int  29h
xchg  ax,dx  ; большинство команд оптимизировано для ax
add  al,4  ; увеличение координаты курсора

cmp  al,16  ; сравнение счётчика с концом строки
jl  l_cicl  ; если меньше, то повтор цикла

xor  al,10010b ; если al=16, то al:=2, если al=18, то al:=0
inc ah


l_cicl:
xchg  ax,dx
int  10h  ; изменение позиции курсора
loop  cicl

quit:
ret   ;выход //1 байт

CSEG  ends
end  main

 

Комментарий: Без комментариев.

 

Решение by Jendos:

; By Jendos 54 byte
; tasm task15.asm
; tlink /t task15.obj


        .model   tiny
        .386
        .code
        org      100h
start:
        mov      ax,3
        int      10h

        xor      dx,dx
        mov      si,8
        push     0cccch

p1:  mov      ax,200h
        int      10h
        pop     ax
        not      ax
        push     ax
        xor      dl,dl
        inc      dh

        mov      cx,16

p:     pop      ax
        ror      ax,1
        push     ax
        jc       black
        mov      al,20h
        jmp      next
black:  mov      al,0dbh
next:   int      29h
        loop     p

        dec      si
        jnz      p1
        pop      ax
        int      20h
        end     start

 

Комментарий: Самый подробный код, но к сожалению и самый большой.

 

У кого есть более короткое решение присылайте указав в теме номер задачи.

Задача #16.

Размер моего решения: 24 байта.

Задание:

Дано два массива: массив символов и массив чисел, например:

String DB 'SAM'

Number DB 2,1,3

Нужно вывести на экран символы из строки String порядковые номера которых, записаны в Number. Т.е. на экране должно получиться:

ASM

Следует учесть, что вместо этих массивов могут быть любые другие. Проверять их на правильность не нужно.

Разрешено: использовать в тексте программы любые метки и макроопределения типа EQU.

Отправить решение до 24.01.2003

NOP - профилактика и методы защиты. Часть II.

Нашлось еще несколько вариантов избавления от nop.

I вариант. Компилировать программу с параметром /m. Этот параметр увеличивает количество проходов. Таким образом компилятор не вставляет nop. Т.е. теперь нужно компилировать так: tasm /m proga.asm. А дальше как обычно.

II вариант. Там где вставляется nop, поставить org $. (Это по мотивам решений Алексея Волкова но немного по-другому).

III вариант. Иногда помогает вставка слова short в функциях вызова (call) и перехода (jmp, j??).

Команда для COMPO.

Может быть вы слышали, что на сайте hugi.de/compo даются задачи (естественно труднее, чем в данной рассылке). Решить одному человеку данную задачу будет непросто, а иногда даже невозможно. Maverick предлагает создать команду (небольшую - человек 5-10) и решать задачи все вместе.

А вообще кто хочет попасть в команду, напишите письмо по адресу: igoryk@yandex.ru. Только прошу учесть, что в этой команде мы только решаем COMPO. И еще прошу писать предложения о том, как это все лучше организовать.

Дискуссия.

Что Вы думаете о законах по поводу защиты авторских прав программистов?

Мнения сюда: igoryk@yandex.ru 

В заключение...

На главной странице сайта http://www.igoryksoft.narod.ru/ будут даны размеры программ лидеров, как только таковые появятся. И так будет с каждой задачей. Узнав, эту информацию каждый может прислать более оптимизированное решение.

Любые предложения по улучшению рассылки, Ваши задачи, вопросы прошу присылать мне на почту, указанную внизу рассылки. 

(с) IgorykSoft Все права защищены! 
URL: http://www.igoryksoft.narod.ru/  E-Mail: Igoryk@Yandex.Ru


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное