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

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

  Все выпуски  

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


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


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


Выпуск #13.

Добрый день, уважаемые подписчики! У нас нововведение: теперь я буду добавлять к Вашим решениям свои комментарии и обсуждения. И еще хочу Вас предупредить: Я никогда не посылаю вложенных файлов! Тем более, если вы меня об этом не просили. А то ко мне штук 10 писем пришло с самыми разными вирусами. Хорошо Norton Antivirus среагировал вовремя...

Кстати обновилась библиотека решений и появился рейтинг. (см. сайт)

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

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

2. Задача #13.

3. Nop - профилактика и методы защиты.

4. Предложение.

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

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

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

1. Eugene - 24? (25) байт.

2. Beeblbrx - 25 байт.

3. G3 - 26 байт.

4. Broken Sword - 27 байт.

5. Denis Maximov - 27 байт.

6. [stl] - 27 байт.

7. Alexey Volkov - 27 байт.

8. Ayl - 28 байт.

9. Elf - 28 байт.

10. Alexey_1 - 29 байт.

11. Odin - 31 байт.

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

Для начала в конце текста Вашего решения напишите:

Stroka DB "1234567"

Len EQU $-Stroka

А теперь, собственно задание: Нужно вывести на экран в одну строку - один символ, два ... семь символов: 1121231234123451234561234567

Решения.

Решение by Eugene:

;Составитель программы Eugene
;способ компиляции:
;fasm 12.asm 12.com
;размер 24 байта
org 100h
cycle:
inc cl ;в CL лежит количество символов на вывод
mov ah, 40h ;используем 40h функцию DOS прерывания
mov bl, 1 ;в BL лежит дескриптор консоли std out
mov dx, Stroka ;DS:DX->адрес строки
int 21h
cmp cl, Len
jne cycle
ret

Stroka db '1234567'
Len = $ - Stroka

 

Комментарий: Если Вы заметили в таблице рекордов рядом с размером программы Eugene я поставил знак вопроса. Дело в том, что реальный размер программы 25 байт, хотя возможно FASM компилирует по-своему. Теперь насчет решения. Решение поражает своей простотой. Никто не догадался сделать аналогичное решение. Хотя кто только начал читать Зубкова увидит описание функции, которая выводит то количество знаков строки, какое указано в cx.

 

Решение by Beeblbrx:

.model tiny
.286
.code
org 100h
start:
mov cl,1
m1: mov si,offset string
m2: lodsb
int 29h
loop m2
lodsb
sub al,'0'-1
xchg ax,cx
loop m1
retn

string db '1234567'
stop_marker db '0'

end start

 

Комментарий: Этому решению явно не хватает комментариев - нет не моих :). Идея решения такая: в AL считывается символ из строки, затем производится вывод на экран. Высчитывается количество оставшихся символов и все повторяется сначала до тех пор, пока не будут выведены все символы. Недостаток решения: строка строго закреплена, т.е. если ввести другую строку в string, то программа работать не будет. И еще не совсем соблюдено условие задачи.

 

Решение by G3:

;Task #12
;tasm /m task.asm
;tlink /x /3 /t task.obj
;26 байт
;by G3

.model tiny
.386
.code
org 100h

Start:
mov di,offset Stroka
inc    bx
mov cx,bx
Output:
mov al,[di]
int 29h
inc   di
loop   Output

cmp bx,Len
jnz Start

ret

Stroka db "1234567"
Len equ $-Stroka

end Start

 

Комментарий: Сначала ответ на вопрос: "Как посылать исходники, чтобы табуляция не пропадала? В HTML?". В любом. Со следующего выпуска сделаю нормальную табуляцию. Алгоритм решения прост: каждый раз считывается и выводится DI символов и с помощью int 29h эти символы выводятся на экран.

 

Решение by Broken Sword:

; Assembler Tasks COMPO #12
; tasm /m entry.asm
; tlink /x /3 /t entry.obj
; entry.com
; by Broken Sword [HI-TECH]
; size: 27 bytes

.model tiny
.code
.386
org 100h 
@@start: 
mov SI,offset stroka
xchg AX,CX
@@S1:
inc CX
push CX

push SI
@@S2:
lodsb
int 29h
loop @@S2

pop SI
pop CX
cmp CX,len
jnz @@S1

ret
stroka db '1234567'
len equ $-stroka

end @@start 

 

Комментарий: Broken Sword сделал как бы два вложенных цикла - один выводит на экран символы, а второй определяет сколько их нужно вывести.

Решение by Denis Maximov:

;Task#12
;Coded by DeMax
;27 bytes
;Tasm 5.0
;tasm task12.asm
;tlink /t task12.obj
.model tiny
.code
org 100h
start:
xor bx,bx
inc bx ;bx=1 - стандартный описатель вывода 
xor cx,cx ;cx - число выводимых символов в строке
main proc near ;прибегнем к помощи рекурсии :)))
inc cx ;увеличиваем с каждым проходом длину выводимой строки
mov ah,40h ;функция записи DOS
mov dx,offset Stroka ; в dx - указатель на строку
int 21h ;выводим строку на экран
cmp cx,Len ;выведена вся строка?
jne main ;если нет, то вызываем сами себя ещё раз
main endp
ret
Stroka DB "1234567"
Len EQU $-Stroka
end start

 

Комментарий: По-моему здесь моего комментария не требуется. Все бы так свои решения оформляли...

Решение by [stl]:

; task12.asm
; by [stl]
; tasm task12.asm
; tlink /x /3 /t task12.obj
; 27 bytes
.386
IDEAL
MODEL tiny
CODESEG
ORG 100h
start:
db 0b1h,len ;mov cl,len
mov dx,OFFSET string
inc bx ;stdout
loop0:
push cx
neg cl
db 080h,0c1h,len+1 ;add cl,len+1
mov ah,40h
int 21h
pop cx
loop loop0
ret
string db "1234567"
len=$-string
end start

 

Комментарий: Вообще-то идея кода как у Beeblebrx, но выводить можно любую строку.

 

Решение by Alexey Volkov: 

; Assembler Tasks COMPO #12
; Способ компиляции: tasm 12.asm, tlink /t 12.obj
; Автор: Alexey Volkov AKA xAL
; mailto:statx@mail.ru, http://xal.newmail.ru/
; Размер: 27 байт
.model tiny
.386
.code
org 100h
start:
mov cl, Len ; Количество символов (для loopa)
org 102h ; Без этого вставляется два nopа :(
; Igoryk обещал объяснить откуда они берутся, но ... ;(
inc bx ; ~ BX=1
mov dx, offset Stroka ; Адрес буфера для функции 40h прерывания 21h
cycle:
push cx ; cx нам будет нужен, чтобы указать количество
; символов для печати, поэтому сохраняем его
mov ax, 4000h+Len+1 ; \ AH = номер функции (40h)
sub al, cl ; | Len+1-cx = кол-во символов для печати
mov cl, al ; /
int 21h

pop cx
loop cycle
ret

Stroka DB "1234567"
Len EQU $-Stroka
end start

 

Комментарий: Специально выделил красным. Читай ниже. Идея кода, как у Eugene, так что комментарии такие же.

 

Решение by Ayl:

; Assembler Tasks COMPO #12
; tasm 12.asm
; tlink /x /t 12.obj
; 12.com
; by Ayl
; size: 28 bytes (7 bytes for data)

.Model TINY
.286

.Code
.StartUp
xchg ax, bp ; загpузить AH значением 9 (BP = 0912 пpи стаpте)
mov bl, '$' ; в BL - пpизнак конца стpоки для функции 9
mov cx, Len ; в CX - количество повтоpений
lea dx, stroka ; адpес стpоки
mov si, dx ; текущий конец стpоки
r:
inc si ; следующая позиция в стpоке
xchg [si], bl ; подставляем в стpоку пpизнак конца, стаpый символ - в BL
int 21h ; выводим текущую подстpоку
xchg [si], bl ; восстанавливаем стpоку и pегистp BL
loop r ; повтоpяем

ret ; выходим

stroka db '1234567'
Len EQU $ - stroka

end

 

Комментарий: Вывод на экран осуществляется функцией 09h прерывания int 21h. Поэтому код меняет строку добавляя в нужном месте знак доллара.

 

Решение by Elf:

; #12
; tasm task12 /z
; tlink task12 /t/3
; size: 28
; by elf
.Model TINY
.286
.Code
.StartUp
push 0b800h ;3
pop es ;1
xor di,di ;2
yo: inc ax ;1
mov cx,ax ;2
lea si,stroka ;3
cy: movsb ;1
inc di ;1
loop cy ;2
cmp al, len ;2
jne yo ;2
ret ;1
stroka db "1234567" ;7
len equ $-stroka
end ;=28

Комментарий: Elf использовал прямое копирование в видеопамять. Интересный код.

 

Решение by Alexey_1:

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

CSEG segment
assume cs:CSEG, ds:CSEG, ss:CSEG, es:CSEG
org 100h
main:

xor si,si;2 байта
xor cx,cx;2 байта

m2:

xchg cx,si;2 байта

inc cx;1 байт

m1:
mov al,stroka[si];4 байта
int 29h;2 байта
inc si;1 байт
loop m1;2 байта

cmp si,len;3 байта (при использовании 2х проходов)
jne m2;2 байта

ret
Stroka DB "1234567"
Len EQU $-Stroka

CSEG ends
end main

Комментарий: выводится строка с первого символа до si. И так каждый раз.

 

Решение by Odin:

 

Комментарий: ну, собственно, все по условию...

 

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

Задача #13.

У меня получилась программа 10 байт.

Задание:

Изменить значения всех регистров кроме IP и одного другого (на выбор) на 0FFFFh.

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

Nop - профилактика и методы защиты.

    Вместо введения. По многочисленным просьбам пишу эту статью-заметку о враге программиста-оптимизатора по размеру - о команде под название Nop.

    Что делает Nop? Вообще Nop - No Operation - отсутствие операции. Применяется он для выравнивания команд - так процессору проще их считывать.

    Как с ним бороться? Давайте сначала рассмотрим пример. Не будем далеко ходить возьмем решение Eugene из этой же рассылки. Если его откомпилировать, то после команды cmp ассемблер (я использую TASM) вставляет nop. Нас интересует только этот отрезок программы. Ну что ж рассмотрим его в отладчике:

-------cut----------

cs:0106 BA1201  mov dx,0112
cs:0109 CD21     int 21
cs:010B 83F907  cmp cx,0007
cs:010E 90         nop
cs:010F 75EF      jne 0100

-------cut----------

Видим, что по смещению cs:010E ассемблер вставил nop. Если мы уберем операцию сравнения, то получим:

-------cut----------

cs:0106 BA0E01 mov dx,010E
cs:0109 CD21    int 21
cs:010B 75F3    jne 0100

-------cut----------

Очевидно, что команда nop исчезла.

Так в чем же дело? А дело в том, что nop добавляется к тем командам, которые имеют нечетную длину. В нашем примере это cmp.

Так как же с этим бороться? Решения-панацеи нет, но я исправлю отрывок и постараюсь объяснить. Исправим отрывок исходного кода на следующий:

-------cut----------

mov dx, Stroka

int 21h
DB
83h, 0F9h, 07h ;коды команды cmp cx,0007
jne cycle

-------cut----------

Заглянув в отладчик увидим, что nop не вставился!

А почему? Да потому, что ассемблер не распознал в готовых кодах команду cmp, а следовательно ему нечего было исправлять!

Т.е. теперь для того, чтобы избавиться от nopa, придется заходить в отладчик, там искать код команды, а затем вставлять как DB? А нельзя ли этот процесс как-нибудь упростить? Наверное можно, но к сожалению я пока не знаю как. Если узнаю, то напишу. Если знаете Вы пишите.

Предложение.

Может быть вы слышали, что на сайте 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
Отписаться
Убрать рекламу

В избранное