|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Assm - [решено] одномерный массив в ассемблере |
|
Assm - [решено] одномерный массив в ассемблере
|
Новый участник Сообщения: 5 |
Добрый день, кто-то может решить задачку по ассемблеру (для 086):
- в одномерном массиве из 16 байт найти минимальное значение и вывести его на индикатор. - описать работу программы в комментариях. Ибо мои познания исчерпались составлением алгоритма: 1 – вводим массив – последовательность из 16 байт произвольных данных в ds 2 – перемещаем первый элемент массива в АХ а второй в ВХ 3 – сравниваем их между собой 4 – меньший оставляем в регистре, больший замещаем следующим элементом массива 5 – повторяем цикл 15 раз 6 – после последнего сравнения содержимое регистра с минимальным элементом выводим на экран. 7 – конец программы. 8 - конец моих знаний. |
|
Отправлено: 20:49, 02-06-2010 |
![]() Ветеран Сообщения: 1328
|
Профиль | Отправить 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
|
Профиль | Отправить PM | Цитировать Oleg_SK, спасибо тебе большое за помощь!
Я только начал изучать но языка ещё не знаю. Поработал только с Debug. Скажи а ты не мог бы дать краткие комментарии по выполняемым действиям? Очень хочу понимать что происходит при командах ![]() В любом случае ещё раз Спасибо тебе! |
Отправлено: 11:12, 03-06-2010 | #3 |
![]() Ветеран Сообщения: 1328
|
Профиль | Отправить 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
|
Профиль | Отправить PM | Цитировать Вполне понятно
![]() С меня килограмм мороженого! Или варенья, на выбор ![]() Будешь в Киеве - заходи в гости, попьём чаю с мороженым ![]() (А ассемблер я освою. Дело принципа.) |
|
Отправлено: 16:06, 03-06-2010 | #5 |
![]() Ветеран Сообщения: 1328
|
Профиль | Отправить PM | Цитировать igor7, я вот только уже очень давно не кодил на асме под MS-DOS, и по этому уже не помню: можно ли там пользоваться 32-ух битными регистрами (типа EBX, ECX т.д.)... По этому возможно тебе нужно будет заменить 32-ух битные регистры на их 16-ти битные варианты (EBX -> BX, ECX -> CX).
|
------- Отправлено: 17:17, 03-06-2010 | #6 |
Новый участник Сообщения: 5
|
Профиль | Отправить PM | Цитировать я так и сделаю.
а пока въезжаю в содержание ![]() Успехов тебе! |
Отправлено: 22:44, 03-06-2010 | #7 |
![]() Ветеран Сообщения: 1328
|
Профиль | Отправить PM | Цитировать Тебе тоже успехов в освоении асма, сайт www.wasm.ru и его форум тебе в помощь; это одна из основных тусовок ассемблерщиков в рунете...
![]() |
------- Отправлено: 22:51, 03-06-2010 | #8 |
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
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 |
|