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

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

  Все выпуски  

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


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


       

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

 

Выпуск  

#43

 

 От автора:

 

Доброго времени суток! В связи с некоторыми неполадками на сервере, а конкретно, его нестабильной работой, было решено отложить данный выпуск. Сейчас ситуация нормализовалась. Все в порядке! Читайте условия задачи, решайте, и присылайте свои решения. 

Приветствуем сегодня двух новых участников: Alx и Uri. Если Вы еще не зарегистрировались, то у Вас еще есть шанс ;).

В выпуске:

 

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

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

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

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

 

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

1. Общая информация.
Название:    Сложение без ADD
Цель  задачи:  Написать модуль, осуществляющий сложение двух чисел, не
используя    операции  сложения,  т.е.  данная  операция  должна  быть
реализована только с помощью сдвигов и логических операций.

2. Правила.
     Согласно п. 3 обработать входные данные и вернуть результат.
  
3. Данные.
     Входные: два байта.
       В  STDIN  Вашей  программы  будет переданы два числа (символы с
       кодом  соответствующим  данном  числу).  Каждый такой символ не
       будет превышать 127 и не будет меньше 0, т.о. при сложении этих
       чисел размер результата не превысит одного байта.
     Выходные: один байт.
       В STDOUT Ваша программа должна будет вернуть результат сложения
       этих двух чисел (символ с соответствующим кодом).

 

Таблица участников.

 

1

 G3, Shur 23 байта

2

 Alx 25 байт

3

 Beeblebrox

35 байт

4

 Uri 40 байт

 

Решения.

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

;Task42 by G3 (tgm80@mail.ru), 23 bytes
;fasm.exe entry.asm entry.com
 org 100h
start:
 mov ah, 06h
  mov dl, 0FFh
 int 21h  ;Get char from STDIN
 push ax
 int 21h              ;Get char from STDIN
 pop dx
L10:
 mov bl,dl
 xor dl,al
 and al,bl    
 shl al,1
 jnz L10
 int 21h              ;Put char to STDOUT
 ret                 

Комментарий: Решение, конечно, достойное 5 баллов... Но все-таки давайте разберемся что здесь к чему ;). Первые строки, я думаю, объяснять не надо: это получение двух байт из STDIN (как Вы помните, эти байты генерировала тестовая программа). Итак, подойдя к метке L10, мы имеем AX = 06XX, DX = 06YY, где XX - второй считанный байт, YY - первый. Пусть для определенности XX = 03h, а YY = 02h - с этими значениями будет проще понять алгоритм работы программы. Проследим выполнение программы (AH и DH всегда равны 06h, BH = 0):

 

 Программа  AL  DL  BL
 L10:   03h = 0011b 02h = 0010b 00h = 0000b
Первая итерация:
 mov bl,dl 03h = 0011b 02h = 0010b 02h = 0010b
 xor dl,al 03h = 0011b 01h = 0001b 02h = 0010b
 and al,bl 02h = 0010b 01h = 0001b 02h = 0010b
 shl al,1 04h = 0100b 01h = 0001b 02h = 0010b
Вторая итерация:
 mov bl,dl 04h = 0100b 01h = 0001b 01h = 0001b
 xor dl,al 02h = 0010b 05h = 0101b 01h = 0001b
 and al,bl 00h = 0000b 05h = 0101b 01h = 0001b
 shl al,1 00h = 0000b 05h = 0101b 01h = 0001b

Вот. Изучив значение регистров во время каждой итерации, и вспомнив таблицу истинности для XOR (1 XOR 1 = 0 XOR 0 = 0; 1 XOR 0 = 0 XOR 1 = 1; ) и AND (1 AND 1 = 1; 0 AND 0 = 1 AND 0 = 0 AND 1 = 0), можно заключить, что алгоритм программы таков:

1. Сохраняем DL. (BL = DL)

2. Ищем "несовпадение" битов в DL и AL, в DL эти биты будут иметь значение 1 (XOR).

3. Ищем "совпадение" битов в AL и BL, в AL эти биты будут равны 1 (AND).

4. Сдвигаем AL на один бит влево (SHL).

5. Если AL не равен 0, то переход на 1.

Теперь поясню, что это за "совпадения/несовпадения". Так результат будет находиться в DL, то работаем с ним: с помощью XOR корректируем DL, а именно, смотрим, где будут суммы 0 + 0 и 1 + 1 - там ставим 1, иначе - 0. Затем с помощью AND корректируем AL на местах переполнений от сумм 1 + 1 (биты AL + DL) ставим 0, т.к. операция AND работает с предыдущим значением DL, т.е. с BL. Теперь с помощью итераций, перестановка битов продолжается, пока все биты AL не "перейдут" в DL.

 

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

;Shur,task42,23b,fasmw
      org 100h
      mov ah,08h
      int 21h           ;get A
      mov dl,al
      int 21h           ;get B
 @:   mov bl,dl
      xor dl,al
      and al,bl
      shl al,1
      jnz @b            ;any carries ?
      mov ah,06h
      int 21h           ;put char
      ret                 

 Комментарий: Костяк программы такой же, как и у G3, но способ получения байтов из STDIN отличается: здесь используется функция 08h.

 

  Решение Alx [25 байта]

;COMPO #42
;by Alx
;size 25

org 100h
start:
 mov dl,0FFh
 mov ah,06h
 int 21h
 mov bl,al
 int 21h
 mov dl,al
loop1:
 mov cl,dl
 xor dl,bl
 and bl,cl
 shl bl,1
 jnz loop1
    int 21h
 ret                 

 Комментарий: Очень приятно, что у нас появляются новые участники ;). А что касается решения, то было потеряно два байта на команде пересылки значений регистров, иначе получилось бы решение, как одно из приведенных выше.

 

 Решение Beeblebrox [35 байта]

; compo #42 entry by Beeblebrox / TMA
; 35 bytes
; assumes bh=0 ch=0
 .model tiny
 .386
 .code
                org     100h
start:
                mov     ah,6
                mov     dl,0FFh
                int     21h
                mov     dh,al
                mov     bl,al   ; bl=dh=A
                int     21h
                mov     dl,al   ; al=dl=B
                xor     dl,dh   ; dl=A^B
                and     dh,al   ; dh=A&B
                or      al,bl   ; al=A|B
                mov     cl,8
loop8:          and     bh,al   ; P & (A|B)
                or      bh,dh   ; A&B | (P & (A|B) )
                shl     bh,1    ; P=( A&B | (P & (A|B) ) )<<1
                loop    loop8
                xor     dl,bh   ; S=A^B^P
                int     21h
                retn
                end     start

 Комментарий: Подробно описаны логические операции. Хорошее оформление.

 

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

; на входе:
; al = bl = 0.
; ah = bh = 0.
; cx = 00FFh
; dx = cs = ds = es = ss
; si = ip = 100h
; cx = sp = 0FFFEh
; bp = 09??h
org 100h
start:
 mov ah, 06h
 mov dl,0FFh
 int 21h ; get char from STDIN
 mov cl, al
 int 21h ; get char from STDIN
 mov ch, al
;=====0
; flags: sz0a0p1c
; ah=06h, младший бит все равно нулевой

; cl - второе число
; ch - первое число, или наоборот, вообще-то глубоко пофиг
; dl - результат, он же контроллер цикла
; dh - младший бит суммы
; ah - старший бит суммы, он же заем
 mov dl,0x80 ; старший бит будет сигнализировать про конец цикла

 1: mov dh, ch ; сначала прооперуем заем
 xor dh, ah ; как просто посчитать младший бит!
 and ah, ch ; теперь у нас новый заем

 sahf  ; прочекаем, а не равен ли случайно перенос единице?
 jc @2
; mov al, ah ; эта и следующая закоментаренные строки я заменил на..
 or ah, cl
 and ah, dh
; or ah, al ; .. условный переход. выиграл 1 байт :)
 2: xor dh, cl ; новый младший бит суммы

 shr cx, 1 ; следующие биты
 rcr dx, 1
 jnc @1
;=====23
 mov ah,06h
 int 21h ; put сhar to STDOUT, ah already = 06h
 ret                                   

 Комментарий: Вот так и надо всем комментировать свои задачи! Только одно но... при отправке решения нужно указывать размер всего файла, а не его части. Приветствуем еще одного COMPO-решателя! 

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

 

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

 

Автор: G3
Название:  Реализация  цикла  без  условных переходов и арифметических
операций. 

Цель задачи: Вывести в STDOUT строку из X символов '#'. 
X вводится из STDIN. 0 < X < 256. 
Для  вывода должна использоваться процедура 6 прерывания 21h
(mov ah,6 / int 21h).

Можно  использовать  только  команды  работы  со  стеком,  безусловные
переходы,  команды  сравнения  битов,  логические  операции и операции
сдвига. 

Полный список допустимых команд: 
AND,  BSF, BSR, BT, BTC, BTR, BTS, CALL, CBW, CLC, CMC, CWD, DEC, INT,
JMP,  LAHF,  LEA,  MOV,  MOVSX, MOVZX, NOT, OR, POP, POPA, POPF, PUSH,
PUSHA,  PUSHF,  RCL,  RCR, RET, ROL, ROR, SAHF, SAL, SALC, SAR, SETxx,
SHL, SHR, STC, TEST, XCHG, XOR

 

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

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

Решения принимаются до: 25 января 2005 года.

Решения посылаются с Вашего аккаунта на сайте. 

Если Вы еще не зарегистрировались, то это можно сделать здесь.

 

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

 

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

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

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

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


http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.asmtasks
Отписаться

В избранное