Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Прошу объяснить код написанной программы.  (Прочитано 13239 раз)
0 Пользователей и 1 Гость смотрят эту тему.
29demon
Новенький

ru
Offline Offline

« : 12-06-2013 14:24 » 

Прошу объяснить код написанной программы. Как она работает??

Программа преобразует 4-х разрядное двоичное число в шестнадцатeричное.

Код: (ASM)
Masm
model   small
stack   256
.data
msg1    db      0ah,0dh,"*Преобразование 4-х разрядного двоичного числа*$"
msg2    db      0ah,0dh,"Биты ¦3210¦ => H$"
msg3    db      0ah,0dh,"Ввод: $"
msg4    db      "  => $"
.code
.486
go:     mov ax,@data
        mov ds,ax
;Вывод заголовка программы
        mov ah,09h
        mov dx,offset msg1
        int 21h
        mov dx,offset msg2
        int 21h
        mov dx,offset msg3
        int 21h
;Ввод двоичного четырехразрядного числа
        mov cx,4
        xor dx,dx
cycle:
        mov ah,01h                     
        int 21h                
        sub al,30h                     
        shl dl,1                       
       

add dl,al                      
        loop cycle
;Вывод строки " => "
        push dx                
        mov ah,09h
        mov dx,offset msg4
        int 21h
        pop dx                 
;Результат: двоичное число в регистре dl
;Вывод шестнадцатеричного числа на экран из dl
        cmp dl,10                      
        jl  less
        add dl,37h                     
        mov ah,02h
        int 21h
        jmp exit
less:   add dl,30h                     
        mov ah,02h
        int 21h

exit:
        mov ax,4c00h
        int 21h
end go
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 12-06-2013 15:21 » 

29demon, дак вроде всё написано в комментариях. Что именно непонятно? Строк тут немало. И для чего нужны эти пояснения, если всё работает?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dmitry
Помогающий

ru
Offline Offline

« Ответ #2 : 12-06-2013 16:39 » 

Так а построчно? Имхо, это из той же серии, что на днях было.
Записан
29demon
Новенький

ru
Offline Offline

« Ответ #3 : 12-06-2013 16:51 » 

29demon, дак вроде всё написано в комментариях. Что именно непонятно? Строк тут немало. И для чего нужны эти пояснения, если всё работает?

Зачем пишем:
".code
.486"
и как работает цикл 
cycle:
        mov ah,01h                     
        int 21h                 
        sub al,30h                     
        shl dl,1
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 12-06-2013 17:17 » 

29demon,
В Turbo Assembler директивы компилятора начинаются с точки. Директива .code указывает, что всё находящееся после неё, должно быть помещено в сегмент кода. Директива .486 указывает, что в коде используются команды процессора Intel 80486 (ну и в силу обратной совместимости - всех предыдущих моделей 8086, 80286, 80386).

Во втором куске я не вижу цикла, поскольку цикл предполагает помимо метки ещё и инструкцию перехода на неё, каковая в приведённом куске отсутствует.

В первых двух строках, судя по номеру прерывания, вызывается функция MS-DOS. Не помню точно, что делает функция 1, но судя по остальному коду, должна запрашивать нажатие клавиши клавиатуры.

В третьей строке вычитается 30h из содержимого регистра AL - видимо там находится результат вышеупомянутой функции. Опять же, точно не помню, но по всем признакам предпринята попытка вычесть ASCII код сивола '0', в результате чего (по причине алфавитной упорядоченности кодировочной таблицы ASCII) код символа преобразуется в соотетствующее ему цифровое значение '0' -> 0, '1' -> 1 и т.д., включая заглавные латинские буквы для случая шестнадцатиричного основания.

Последняя строчка в контексте предыдущих трёх смысла не имеет.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 13-06-2013 07:07 » 

Последняя строчка в контексте предыдущих трёх смысла не имеет.

Имеет. Через флаг переноса.


29demon, ну что, теперь тебе стало понятнее?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
29demon
Новенький

ru
Offline Offline

« Ответ #6 : 13-06-2013 09:21 » 

29demon,
В Turbo Assembler директивы компилятора начинаются с точки. Директива .code указывает, что всё находящееся после неё, должно быть помещено в сегмент кода. Директива .486 указывает, что в коде используются команды процессора Intel 80486 (ну и в силу обратной совместимости - всех предыдущих моделей 8086, 80286, 80386).

Во втором куске я не вижу цикла, поскольку цикл предполагает помимо метки ещё и инструкцию перехода на неё, каковая в приведённом куске отсутствует.

В первых двух строках, судя по номеру прерывания, вызывается функция MS-DOS. Не помню точно, что делает функция 1, но судя по остальному коду, должна запрашивать нажатие клавиши клавиатуры.

В третьей строке вычитается 30h из содержимого регистра AL - видимо там находится результат вышеупомянутой функции. Опять же, точно не помню, но по всем признакам предпринята попытка вычесть ASCII код сивола '0', в результате чего (по причине алфавитной упорядоченности кодировочной таблицы ASCII) код символа преобразуется в соотетствующее ему цифровое значение '0' -> 0, '1' -> 1 и т.д., включая заглавные латинские буквы для случая шестнадцатиричного основания.

Последняя строчка в контексте предыдущих трёх смысла не имеет.

А в двух словах объяснить можете как эта программа преобразует число ??

Записан
sss
Специалист

ru
Offline Offline

« Ответ #7 : 13-06-2013 10:04 » 

Использует сервис MSDOS
Записан

while (8==8)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 13-06-2013 11:37 » 

29demon, какое число преобразует? Эта программа никаких чисел не преобразует. Она их только вводит и выводит, как тут правильно замечено,
Цитата: sss
Использует сервис MSDOS

Если ты даже не знаешь, что такое представление числа в двоичной, десятичной, шестнадцатиричной системах, то зачем ты вообще в ассемблер полез? Это не более чем формат числа в строке, а не само число.
« Последнее редактирование: 13-06-2013 11:41 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
29demon
Новенький

ru
Offline Offline

« Ответ #9 : 13-06-2013 13:19 » 

29demon, какое число преобразует? Эта программа никаких чисел не преобразует. Она их только вводит и выводит, как тут правильно замечено,
Цитата: sss
Использует сервис MSDOS

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

Я знаю представление. Умею переводить с одной системой в другую.

Это контрольная работа по ассемблеру. До этого задания были легкие все понятно а тут не чего не понятно.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 13-06-2013 15:36 » 

29demon, ну если не знать ассемблера, то, конечно, непонятно. Другой вопрос: как так получилось, что контрольная (т.е. проверяющая должные быть у тебя знания) по ассемблеру задана, а ты ассемблер будто впервые в жизни видишь? Куда пропал этап собственно учёбы?

И раз ты умеешь переводить числа из одного представления в другое, то, наверно, ты это делаешь цифра за цифрой - т.е. работаешь со строками, в которые записываешь цифры и из которых эти цифры берёшь одна за другой. Ну и программа делает то же самое. Чудес тут нету.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
sss
Специалист

ru
Offline Offline

« Ответ #11 : 14-06-2013 00:50 » 

До этого задания были легкие все понятно а тут не чего не понятно.

Вам непонятно что такое и как используется сервис MSDOS? Это как вызов библиотеки DLL, только не напрямую, а через прерывание 21h.
Перед вызовом номер функции указывается в регистр ah и, в зависимости от функции, дополнительные параметры через другие регистры.
Например код из примера наверняка выводит строку msg1 на дисплей.

Код:
  mov ah,09h
  mov dx,offset msg1
  int 21h

Здесь номер функции 9, смещение строки в dx, а вот сегмент где я не вижу. Возможно берётся текущий ds - надо поднять документацию и проверить.
На память - должен быть в ex.

Посмотрел - правильно, используется ds.

В общем:

Вводится 4 символа с клавиатуры. Ожидается что это или символ 0 (30h) или 1 (31h) после выполнения функции MSDOS 01 в регистре al.
Вычитая из al 30h мы получаем или 0 или 1. Накопление результата в dl (сдвиг dl + al).. Далее проверка dl меньше 10 - значит просто прибавить
30h иначе прибавить 37h (10 + 37h = 41h - символ A).

« Последнее редактирование: 14-06-2013 01:27 от sss » Записан

while (8==8)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 14-06-2013 07:20 » 

Цитата: sss
Это как вызов библиотеки DLL
Не стоит в качестве аналогии к непонятному приводить другое столь же непонятное. Как пить дать, он понятия не имеет, как устроены DLL, и как это работает.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
sss
Специалист

ru
Offline Offline

« Ответ #13 : 14-06-2013 08:06 » 

Согласен.. При это неудачное сравнение.
Записан

while (8==8)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines