Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Assm - [решено] одномерный массив в ассемблере

Ответить
Настройки темы
Assm - [решено] одномерный массив в ассемблере

Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


Добрый день, кто-то может решить задачку по ассемблеру (для 086):

- в одномерном массиве из 16 байт найти минимальное значение и вывести его на индикатор.
- описать работу программы в комментариях.

Ибо мои познания исчерпались составлением алгоритма:

1 – вводим массив – последовательность из 16 байт произвольных данных в ds
2 – перемещаем первый элемент массива в АХ а второй в ВХ
3 – сравниваем их между собой
4 – меньший оставляем в регистре, больший замещаем следующим элементом массива
5 – повторяем цикл 15 раз
6 – после последнего сравнения содержимое регистра с минимальным элементом выводим на экран.
7 – конец программы.
8 - конец моих знаний.

Отправлено: 20:49, 02-06-2010

 

Аватара для Oleg_SK

Ветеран


Сообщения: 1328
Благодарности: 144

Профиль | Отправить PM | Цитировать


igor7
Давно я уже не кодил на асме (особенно под DOS), но попытаюсь помочь тебе. Ты не совсем четко определил условия задачи, по этому я сделаю следующие допущения:
1) Программа должна быть написана с помощью MASM;
2) Программа будет работать в среде MS DOS;
3) Все значения в массиве беззнаковые (т.е. отрицательных значений в нем нет);
4) Итоговое минимальное значение будет выводиться в шестнадцатеричном виде.
5) В итоге ты желаешь получить исполняемый COM-файл.

Код: Выделить весь код
model tiny
.code
.386
org 100h

start:
mov ebx, offset Arrey
mov ecx, 0Fh
mov al, byte ptr[ebx]
inc ebx
lo:
mov ah, byte ptr[ebx]
cmp al, ah
jbe cont ; 
mov al, ah
cont:
inc ebx
dec ecx
jnz lo
; теперь нужное тебе мин. значение находится в регистре al.
; Теперь выводим его на экран.
mov dh, al
and dh, 0Fh
shr al, 4
call print
mov al, dh
print:
cmp al, 10
sbb al, 69h
das
mov dl, al
mov ah, 2
int 21h
ret

Arrey db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 ; это массив

end start
Вот и все.

З.Ы: Я не проверял этот код на работоспособность...

-------
Здесь вместо "Спасибо" принято щелкать на "Полезное сообщение" у тех постов, которые вам помогли, или показались полезными.


Последний раз редактировалось Oleg_SK, 03-06-2010 в 01:58.

Это сообщение посчитали полезным следующие участники:

Отправлено: 01:37, 03-06-2010 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


Oleg_SK, спасибо тебе большое за помощь!

Я только начал изучать но языка ещё не знаю. Поработал только с Debug.
Скажи а ты не мог бы дать краткие комментарии по выполняемым действиям?
Очень хочу понимать что происходит при командах

В любом случае ещё раз Спасибо тебе!

Отправлено: 11:12, 03-06-2010 | #3


Аватара для Oleg_SK

Ветеран


Сообщения: 1328
Благодарности: 144

Профиль | Отправить PM | Цитировать


igor7
Цитата:
Очень хочу понимать что происходит при командах.
А что, книг по Ассемблеру у тебя нет? Это простой код и тебе будет гораздо полезней разобраться с ним самостоятельно; только так можно чему-то научиться, т.к. полученое без труда легко забывается. В общем, тебе решать...

Комментарий к приведенному коду:
Между метками start и lo производится подготовка к циклу, в котором производится поиск минимального значения в массиве Arrey. В процессе этой подготовки делается следующее:
1) В регистр EBX заносится адрес первого элемента массива Arrey. Этот регистр будет служить для обращения к массиву.
2) Регистр ECX будет содержать счетчик цикла; в него заносится значение 0Fh (это 15 в шестнадцатеричном виде). В принципе можно вместо 0Fh использовать 15, но лучше сразу начинать привыкать пользоваться шестнадцатеричными значениями.
3) В регистр al помещается значение из первого элемента массива Arrey, а адрес в регистре EBX увеличивается на 1, чтобы указывать на следующий элемент массива.
Между меткой lo и моим комментарием находится тело цикла, в котором на каждой его итерации значение очередного элемента массива сравнивается со значением в регистре al (который содержит самое маленькое из найденных на данный момент значений массива). Если новое значение оказывается меньше сохраненного в регистре al, то оно заносится в этот регистр, в противном случае происходит переход к метке cont для завершения текущей итерации цикла. При завершении итерации цикла адрес в регистре EBX увеличивается на 1, чтобы указывать на следующий элемент массива (причем на последней итерации цикла на этом этапе адрес уже выходит за пределы массива). Счетчик цикла в регистре ECX уменьшается на единицу, после чего, если он еще не достиг нулевого значения, происходит переход на метку lo для следующей итерации. В общем-то, все это в целом соответствует указанному тобой алгоритму (с п.2 по п.5); правда я вместо указанных тобой 16-ти битных регистров AX и BX использовал более соответствующие моменту 8-ми битные al и ah (которые являются составными частями регистра AX(EAX)). Конечно для оптимизации этого алгоритма по времени работы для выборки значений из массива лучше использовать 16-ти битный регистр (или 32-ух битный, что еще лучше), но тогда кол-во необходимого кода увеличится и он будет сложнее для понимания, да и особого смысла в этом в данном случае нет. Далее, между моим комметарием и последней инструкцией программы (ret) находится код печатающий найденное значение (оно находится в регистре al) на экране монитора. Тут нужно сделать небольшое отступление: массив состоит из элементов размером 1 байт (8 бит). Такой же размер имеет и регистр al, хранящий найденное мин. значение. С учетом сделанного мной допуска о беззнаковости числовых значений в элементах массива, в одном байте может храниться любое числовое значение из диапазона 0...255 (00...FF в шестнадцатеричном виде). Как можно увидеть, для отображения значения одного байта достаточно двухразрядного шестнадцатеричного числа. Теперь смотри внимательно: у шестнадцатеричного числа первый разряд является старшим, а последний младшим. Например, возьмем число 5F. Тут 5 является старшим разрядом, а F - младшим. Применительно к 8-ми битному значению (1 байтному) старший разряд шестнадцатеричного числа представлен значением старших 4 бит 8-ми битного значения (эти биты имеют номера с 7 по 4), а младший разряд соответственно представлен младшими четырьмя битами (эти биты имеют номера с 3 по 0). Обрати внимание на то, что биты в байте считаются с права на лево начиная с 0. Это я рассказал для того, чтобы ты смог понять код печатающий числовое значение на экране монитора. Теперь перейду к объяснению самого кода. Раз однобайтное число может быть представлено двухразрядным шестнадцатеричным значением, то печать выполняется в два прохода: сперва печатается старший разряд числа, а затем младший. Так как этот код печати довольно сложен для начинающего, прокомментирую его более подробно:
Код: Выделить весь код
; Следующие три инструкции предназначены для выделения из 8-ми битного значения двух 4-ех битных, которые отвечают за соответствующие разряды в шестнадцатеричном числе.
mov dh, al   ; Копируем найденное значение в регистр dh
and dh, 0Fh ; Сбрасываем (обнуляем) старшие 4 бита значения. Теперь в регистре dh хранится только младший разряд шестнадцатеричной цифры.
shr al, 4       ; Производим сдвиг значения в регистре al так, чтобы значения его бит с номерами с 7 по 4 переместились соответственно в биты с номерами с 3 по 0. Старшие 4 бита при этом сбрасываются, а то, что хранилось в младших четырех битах до этого сдвига - теряется (кроме самого старшего бита, значение которого помещается в флаг CF, но в данном случае об этом можно забыть), замещаясь значениями из старших четырех бит. Теперь в регистре al хранится только старший разряд шестнадцатеричной цифры.

call print ; Производим вызов кода с метки print как подпрограммы (после того как там выполнится инструкция ret управление будет передано на инструкцию следующую за этой call. В данном случае print вызывается для печати старшего разряда шестнадцатеричного числа. Обрати внимание на то, что печатающий код не выделен в отдельную подпрограмму; это может быть не привычным для человека знакомого только с ЯВУ).
mov al, dh ; Теперь к печати готовится младший разряд шестнадцатеричного числа; для чего оно помещается в регистр al, как того ожидает код следующий за меткой print. Обрати внимание на то, что на этот раз код находящийся за меткой print будет выполнен в линейном порядке, а не вызван как подпрограмма; соответственно на этот раз при выполнении инструкции ret произойдет не выход из подпрограммы, а выход из программы и ее завершение.
print: ; Предпологается, что печатаемый разряд шестнадцатеричного числа находится в регистре al.
;Следующие три инструкции предназначены для перевода числового значения находящегося в регистре al в соответствующий ему ASCLL-код (см. описание инструкции DAS).
cmp al, 10
sbb al, 69h
das

Следующие три инструкции предназначены для печати на экране монитора полученного ASCLL-кода цифрового значения. Для печати используется стандартная функция MS DOS
mov dl, al  ; Помещаем код печатаемого символа в регистр dl, как того требует нужная функция MS-DOS.
mov ah, 2 ; В регистр ah помещаем номер нужной нам функции, как того требует нужная функция MS-DOS...
int 21h     ...и вызываем прерывание 21h для вызова нужной функции.

; После выполнения следующей инструкции происходит либо выход из подпрограммы print, либо завершение программы; в зависимости от того, был ли код с меткой print вызван как подпрограмма инструкцией call или выполнение программы до него дошло в линейном порядке.
ret
Ну и осталось рассмотреть использованные команды ассемблера:
Код: Выделить весь код
model tiny ; Объявляем модель работы с памятью, необходимую для программы. Для COM-программы необходимой является модель tiny.
.code ; Сообщаем ассемблеру, что дальше идет секция кода.
.386 ; Указываем ассемблеру модель процессора, набором инструкций которого ограничивается программа.
org 100h ; Эта команда необходима для COM-программ, которые загружаются на страницу памяти со смещением 100h от ее начала, и это должно быть учтено при ассемблировании программы ассемблером.
***
end start ; Эта команда является последней в программе, о чем и сигнализирует ассемблеру, указывая при этом точку входа программы (entry point), с которой будет начинаться исполнение программы; в данном случае это метка start.
Вот собственно и все...

З.Ы: Надеюсь я объяснил достаточно понятно...

-------
Здесь вместо "Спасибо" принято щелкать на "Полезное сообщение" у тех постов, которые вам помогли, или показались полезными.

Это сообщение посчитали полезным следующие участники:

Отправлено: 14:37, 03-06-2010 | #4


Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


Вполне понятно Спасибо ещё раз!

С меня килограмм мороженого! Или варенья, на выбор

Будешь в Киеве - заходи в гости, попьём чаю с мороженым )

(А ассемблер я освою. Дело принципа.)

Отправлено: 16:06, 03-06-2010 | #5


Аватара для Oleg_SK

Ветеран


Сообщения: 1328
Благодарности: 144

Профиль | Отправить PM | Цитировать


igor7, я вот только уже очень давно не кодил на асме под MS-DOS, и по этому уже не помню: можно ли там пользоваться 32-ух битными регистрами (типа EBX, ECX т.д.)... По этому возможно тебе нужно будет заменить 32-ух битные регистры на их 16-ти битные варианты (EBX -> BX, ECX -> CX).

-------
Здесь вместо "Спасибо" принято щелкать на "Полезное сообщение" у тех постов, которые вам помогли, или показались полезными.


Отправлено: 17:17, 03-06-2010 | #6


Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


я так и сделаю.
а пока въезжаю в содержание

Успехов тебе!

Отправлено: 22:44, 03-06-2010 | #7


Аватара для Oleg_SK

Ветеран


Сообщения: 1328
Благодарности: 144

Профиль | Отправить PM | Цитировать


Тебе тоже успехов в освоении асма, сайт www.wasm.ru и его форум тебе в помощь; это одна из основных тусовок ассемблерщиков в рунете...

-------
Здесь вместо "Спасибо" принято щелкать на "Полезное сообщение" у тех постов, которые вам помогли, или показались полезными.


Отправлено: 22:51, 03-06-2010 | #8



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Assm - [решено] одномерный массив в ассемблере

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Assm - [решено] Задачи на ассемблере Snake750 Программирование и базы данных 12 07-03-2010 17:31
VBS/WSH/JS - задача. инфа. массив одномерный. Triz Программирование и базы данных 3 18-05-2009 06:58
Assm - Помогите решить задание на ассемблере Wild_cat Программирование и базы данных 3 10-03-2009 09:49
графика на ассемблере под дос JCooper Программирование и базы данных 8 21-09-2004 09:46
программа на Ассемблере himik Программирование и базы данных 9 22-11-2003 04:40




 
Переход