Правила - Рейтинг участников - Библиотека решений

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

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

2. Shur (15 байт)

3. Beeblebrox (17 байт)

4. Broken Sword (18 байт)

5. G3 (19 байт)

6. Ayl (21 байт)

7. Odin (21 байт)

8. Denis Maximov (21 байт)

 

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

Проверить является ли введенное число двоичным.

Решение by Shur:

;by Shur
;15 bytes
;fasm task14.asm task14.com
org 100h

;mov 	si,100h
xchg 	ax, dx
xchg 	ax,si
_check:
add 	al,0feh
salc
or 	dl,al
int 	21h
sub 	al,30h
cmp 	al,0dh-30h
jne 	_check
ret

 

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

Идея кода: Используется функция 01h прерывания 21h для ввода символов. После ввода символа определяется: введен 0 или 1. Для этого от ASCII-кода символа отнимается ASCII-код "0". Если был нажат Enter, тогда преобразование передаст в AL 0Dh-30h. И выйдет из программы. Иначе AL дополнится до 0FFh или 0FEh (в зависимости от того какой символ был введен). Если же введен недопустимый символ, то команда вызовет переполнение (CF=1). Команда salc (у кого не работает используйте DB 0D6h) устанавливает AL=CF. Т.е. если введен допустимый символ, то AL=0. Далее с помощью команды or над битами DL совершается логическое ИЛИ по маске в AL. Т.е. если AL=0FFh, то и DL=0FFh, но если AL=0, но DL=0FFh, т.е. DL не изменяется.

 

Решение by Beeblebrox:

; c14 entry by Beeblebrox / TMA
; 17 bytes
.model tiny
.code
.386
              	org     100h
start:     	cwd                       	; dl=0
m1:       	shr     	al,1            	; al=0 only if al==0 or al==1
              	cbw     	                  	; ah=0
              	jz         	int16
              	or        	dl,cl           	; dl=-1 (nonbinary chars encountered)
int16:    	int       	16h            	; fn0 - Input char
             	sub     	al,'0'
              	cmp    	al,0Dh-'0' 	; wait for Cr
              	jne     	m1
quit:      	retn
              	end     	start

 

Комментарий: Идея этого кода сходна с идеей первого решения, но в нем другая обработка введенных символов.

Идея кода: Командой cwd нулируется регистр DL. Если был занят младший бит числа (0 или 1), то AL=0. С помощью cbw в AH заносится номер функции для считывания с клавиатуры. Затем точно также как и в первом задании изменяются биты DL.

 

Решение by G3:

;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

 

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

Идея кода: Запрашивается символ для ввода, затем командой or al, 1 отбрасываются все биты кроме самого младшего. Если была введена единица, то команда xor al, 31h сделает флаг ZF=1, если же был введен ноль, то ZF стал равен единице ранее, и программа возвратится на начало. Если же был введен другой символ, то DL=FFh.

 

Решение by Alexey Volkov:

; 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

 

Решение by Ayl:

; Assembler Tasks COMPO #14
; tasm 14.asm
; tlink /x /t 14.obj
; 14.com
; by Ayl
; size: 21 bytes

.Model TINY
.286

.Code
.StartUp 
xchg 	ax, dx 	; DX = 0
A:
mov 	ax, si 	; AX = 0100
int 	21h

cmp 	al, 0dh 	; Hажата клавиша Enter - конец ввода
je 	Exit

sub 	al, 30h 	; Пpовеpим на 0
jz 	A 	; Если да, то DL менять не надо
dec 	al 	; и на 1
jz 	A

dec 	dx 	; Установить DL в FF
jmp 	short A

Exit:
ret
end

 

Комментарий: Когда автор сам ставит комментарии к своей программе - это всегда приветствуется! И моих комментариев не надо.

 

Решение by Odin:

; task 14 by Odin 21 байт
; fasm task14.asm task14.com
org 100h
kbread:
mov 	ah, 01h
int 	21h
cmp 	al, 30h 	; если 0 вводим дальше
je 	kbread
cmp 	al, 31h 	; если 1 вводим дальше
je 	kbread
cmp 	al, 0Dh 	; если ни то ни другое, но зато Enter
jne 	err 	; тогда выход, если не Enter, то прыгаем
ret
err:
mov 	dl, 0FFh ; сюда и опять вводим дальше
jmp 	kbread

 

Комментарий: Я это решение публикую, но не засчитываю. DX=CS при старте программы, а не 0. В принципе добавив нулирование DX перед началом программы ее размер увеличится на 2 байта: 21+2=23 байта.

 

Решение by Denis Maximov:

;task#14
;21 bytes
;Coded by DeMax
;Tasm 5.0
;tasm task#14.asm
;tlink /t task#14.obj
.model tiny
.code
org 100h
start:
xor 	dl,dl 	;очистка dl
begin:
mov 	ah,1
int 	21h 	;получим код символа
cmp 	al,0Dh 	;Enter?
je 	exit 	;да, завершаем работу
shr 	al,1 	;избавимся от младшего бита
cmp 	al,18h 	;"0,1"?
je 	begin 	;двоичное число
mov 	dl,0FFh 	;строка
jmp 	begin
exit:
ret
end 	start
Hosted by uCoz