Решения задачи #14.
5. G3 (19 байт)
Проверить является ли введенное число двоичным.
;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 не изменяется.
; 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.
;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.
; 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 |
; 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 |
Комментарий: Когда автор сам ставит комментарии к своей программе - это всегда приветствуется! И моих комментариев не надо.
; 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 байта.
;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 |