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

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

  Все выпуски  

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


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


       

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

 

Выпуск

#41

 

От автора:

 Добрый день! Вот и сорок первый выпуск рассылки оказался у Вас в ящике. Я тут дизайн немного поменял.... Кстати, сайт доступен по старому адресу: www.codeclimber.com Добро пожаловать!

В выпуске:

1. Решение задачи #40.

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

3. Послесловие.

Решение задачи:

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

Ваша программа должна установить графическое разрешение экрана 320х200
(режим  13h),  нарисовать  картинку, дождаться нажатия любой клавиши и
завершить  свое  выполнение, вернув экрану текстовое разрешение (режим
03h).

Рисунок должен занять весь экран - 64000 точек.

Алгоритм   рисования.   Программа  обрабатывает  все  точки  экрана  c
координатами  X (от 0 до 319) и Y (от 0 до 199) и меняет их цвет. Цвет
точки  с  координатами (X;Y) вычисляется по формуле (X^2 - Y^2) div 2.
На Basic этот алгоритм мог быть реализован так: 

For X = 0 To 319
    For Y = 0 To 199
     PSet (X, Y), ((X * X - Y * Y) \ 2)
    Next
Next

!  Так  как режим 13h поддерживает только 256 цветов, то реальный цвет
точки  будет  равен младшему байту регистра или переменной, которую Вы
использовали для вычислений. 
!  Нельзя  модифицировать  предложенный  алгоритм  (нельзя   например,
размножать часть картинки по экрану и пр.)
!  Программа  не  работает  с командной строкой, поэтому можно считать
AX=BX=0.
 

В решении задачи приняло участие 7 человек, но засчитать я смог только 6.

Итак, Таблица участников сегодня такова:

 

1

G3, Shur, Tyler Durden

37 байт

2

Black_Mirror

40 байт

3

FatMoon

42 байта

4

Sanek

46 байт

 

Несколько слов по поводу.

Я считаю, что это COMPO удалось, судя по количеству присланных решений. На форуме было посвящено этому задание целых четыре темы. Так что на будущее можно будет учесть, что нравится подписчикам!

 

А теперь я расскажу как можно поэкспериментировать с программами, приведенными ниже (это для тех, кого не было в форуме).

1. Попробуйте не делить, а умножать, либо делить на другое число (не 2) - будет меняться масштаб изображения.

2. Попробуйте не вычитать, а складывать квадраты - появятся окружности.

3. Хотите движения - заходите на форум - G3 придумал :).

Решения.

 Решение by G3 [37 байт]

;Task40 by G3 (tgm80@mail.ru), 37 bytes
;tasm /m entry.asm, tlink /t entry.obj
  .model tiny
  .code
  .486
  org 100h
start:    ;assume ax=0, bx=0, di=0FFFEh, si=100h
  dw 320 ;inc ax; первый байт инструкции add bx,ax
  ret  ;второй байт инструкции add bx,ax 
  mov al,13h
   int 10h ;установка режима 320x200x256
  push 0A000h
   pop es
L10:  
  dec bx ;в конце цикла bx будет равен 3 !!!
  dec di
  cwd
  mov ax,di
  div word ptr [si] ;ax=di/320=Y, dx=di%320=X
  mul al  ;ax=Y^2
  xchg ax,dx
  mul al  ;ax=X^2
  sub ax,dx  ;ax=X^2-Y^2
  shr ax,1  ;ax=(X^2-Y^2)/2
  stosb
  dec di
  jne L10
  int 16h
  xchg ax,bx ;mov ax,3
   int 10h ;возврат в текстовый режим
    ret
  end start

На мой взгляд это самое оригинальное решение. Вообще-то использование данных, как кода не всегда красиво, но здесь оно явно в тему. Так держать!

 

Решение by Shur [37 байт]

;by Shur
;37 bytes
;fasmw

 add cx,320-255 ;set cx=320, first opcode byte=83h

 mov al,13h     ;
 int 10h        ;set video mode

 push 0a000h    ;
 pop es         ;video segment

_point:
 cwd            ;zero dx
 mov ax,di
 div cx         ;ax-Y, dx-X
 mul al         ;Y*Y
 xchg ax,dx
 mul al         ;X*X
 sub ax,dx
 shr ax,1
 stosb

 inc bx         ;loop 2^16 times
 jnz _point     ;

 xchg ax,cx     ;ah=1
 int 21h        ;kb input

 xchg ax,bx     ;ax=0
 lodsb          ;al=83h
 int 10h        ;reset video
 ret

 Это решение мне тоже очень понравилось. Единственное, к чему можно придраться, так это то, что программа по завершении в текстовый режим переходит, но экран не очищает.

 

Решение by Black_mirror [40 байт]

 

  ;COMPO #40
  ;Автор: 
  ;Размер решения: 40
  ;Описание алгоритма: Я его пока еще сам не понял 8)
  ;Компилятор: fasm
   org 256
   mov al,13h
   int 10h
   mov dx,0a000h
   mov ds,dx
  
   mov bp,dx
      .l0:
   mov cx,320*2
      .l1:
   dec bx
   ror dx,1
   mov [bx],dl
   rol dx,1
  
   dec cx
   sub dx,cx
   loop .l1
  
   inc bp
   sub dx,bp
   inc bp
   jnz .l0
  
   int 16h
   mov ax,3
   int 10h
   ret

 

Решение by FatMoon [42 байта]

;Compo 40
;FatMoon [Hi-Tech]
;42 bytes
;
;Description:
;=============================
;screen 13h
;for y=199 downto 0
;   for x=319 downto 0
;      point(x,y)=lowbyte[(x+y)*(x-y) div 2]
;   next x
;next y
;wait_key_pressed
;screen 3
;end
;=============================
 .model tiny
 .code
 .286
 .startup

 mov al, 13h  ;ax=0 by rules
 int 10h

 push 0a000h  ;.286 and high
 pop es
 mov di, 63999
 std

 mov bl, 199  ;bx was 00ffh by rules
 1: mov si, 319
 2: lea ax, [bx+si] ;ax=bx+si
 mov dx, si
 sub dx, bx  ;dx=si-bx
 imul dx  ;x^2-y^2=(x+y)(x-y)
 shr ax,1  ;div 2
 stosb
 dec si
 jns @2  ;include 0
 dec bx
 jns @1

 int 16h  ;ax was 0 because last (0*0-0*0)/2
 mov ax, 3  ;can't mov al,3 :(
 int 10h
 ret
end

 

Решение by Sanek [46 байта]

  Автор: Sanek
  Размер: 46
  
                    .model  tiny
                  .code
                  org     100h
  start:
                  mov     al,13h
                  int     10h
                  push    0A000h
                  pop     es
                  mov     di,64000-1
                  std
                  mov     bx,200
  @NextRow:       mov     cx,320
                  mov     ax,bx
                  mul     ax
                  mov     bp,ax
  @NextCol:       mov     ax,cx
                  mul     ax
                  sub     ax,bp
                  shr     ax,1
                  stosb
                  loop    @NextCol
                  dec     bx
                  jnz     @NextRow
                  mov     ah,0
                  int     16h
                  mov     al,3h
                  int     03h
                  ret
                  end     start

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

Сегодня мы будем решать задачу, которую предложил Shur.

 

Условие задачи #41:

Задача: вычислить функцию CRC32 файла.

CRC     является     достаточно   надежным   средством   контроля   за
непредумышленным  искажением  передаваемой  информации  и используется 
например, в архиваторах и сетевых протоколах

Вам  предлагается  написать программу, вычисляющую эту самую CRC. Ваша
программа  должна  прочитать  содержимое  входного  файла   из  STDIN,
вычислить  32-х битное значение CRC32, используя стандартный алгоритм,
преобразовать   полученное   значение  в  строковое  шестнадцатеричное
представление,  и  уже  его  вывести  на стандартное устройство вывода
STDOUT. 

Стандартный   алгоритм,   а  также  его  тестовую  реализацию,  можно
посмотреть в архиве. 

! должны быть выведены ровно 8 символов
! шестнадцатеричные цифры используются заглавные
!  для  тех,  кто  под NTVDM: считать, что старшие половинки регистров
(те, что E) при старте равны нулю, нельзя. 
! размер файла не ограничен 64k. и даже 4Gb :)
 

Архив с тестирующей программой можно скачать здесь.

Вопросы по этой задаче обсуждаются здесь.

Решения принимаются до 30 августа 2004 года.

Решения посылаются с Вашего аккаунта на сайте. Если Вы еще не зарегистрировались, то это можно сделать здесь.

 

Послесловие:

На главной странице "Задач" [http://codeclimber.com/cgi-bin/asmtasks.cgi] будут даны размеры программ лидеров, как только таковые появятся, а также все официальные дополнения к условию задачи. И так будет с каждой задачей. Узнав, эту информацию каждый может прислать более оптимизированное решение.

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

URL: http://codeclimber.com  E-Mail: compo@codeclimber.com

[c] CodeClimber Все права защищены, 2003-2004


http://subscribe.ru/
http://subscribe.ru/feedback/
Адрес подписки
Отписаться

В избранное