Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты данной рассылки

Boriss
Статус: Академик
Рейтинг: 2644
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 2350
∙ повысить рейтинг »
vladisslav
Статус: 8-й класс
Рейтинг: 1323
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1437
Дата выхода:10.04.2011, 16:30
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:213 / 67
Вопросов / ответов:3 / 3

Вопрос № 182711: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: По прерыванию INT1 ввести исходные данные через порт P0. Выполнить подпрограмму (В массиве, состоящим из N 16-разрядных кодов, определить минимальный элемент и зафиксирова...


Вопрос № 182729: Здравствуйте! Прошу помощи в следующем вопросе: Принять два числа по последовательному каналу: ввод программный, скорость 4800 бит.с, режим 1 Выполнить сложение чисел В зависимости от запроса прерываняи INT0 или INT1 данные вывести побайтно ...
Вопрос № 182735: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:Помогите с программой под ОС Windows XP, TASM.Программу прокомментировать. Условия программы: Дана двухбайтовая двоичная строка. Найти в ней самую длинную группу подряд идущих е...

Вопрос № 182711:

Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:
По прерыванию INT1 ввести исходные данные через порт P0. Выполнить подпрограмму (В массиве, состоящим из N 16-разрядных кодов, определить минимальный элемент и зафиксировать его адрес. Массив находится во внешнем ОЗУ ). По запросу INT0 вывести результаты через последовательный канал, работающий в режиме 1 программно на скорости 4800 бит\с.
ОМК Intel 8051.
Помогите пожалуйста. Поиск минимума и его адреса:

Код:
Ljmp start
org 30h
start:
arr_adr_lo equ 30h ;мл байт адреса массива
arr_adr_hi equ 31h ;ст байт адреса массива
arr_count equ 32h ;длина массива
min_adr_lo equ 33h ;мл байт адреса минимального элемента
min_adr_hi equ 34h ;ст байт адреса минимального элемента
work_adr_lo equ 35h ;мл байт адреса текущего элемента
work_adr_hi equ 36h ;ст байт адреса текущего элемента
min_lo equ 37h ;мл байт минимального элемента
min_hi equ 38h ;ст байт минимального элемента

mov sp, #70h
mov arr_adr_lo, #16h
mov arr_adr_hi, #00h
mov arr_count, #6
mov acc, arr_count
jz eee
call min ;ищем адрес минимального элемента

sjmp eee

min: ;поиск адреса минимального элемента
push acc
push psw
push dpl
push dph
mov dpl, arr_adr_lo
mov dph, arr_adr_hi
mov min_lo, #0ffh ;min = 0ffffh
mov min_hi, #0ffh
mov r2, arr_count ;число элементов

loop:
mov work_adr_lo, dpl ;адрес текущего элемента
mov work_adr_hi, dph
movx a, @dptr ;мл байт текущего элемента
mov r3, a
inc dptr ;на адрес ст байта
movx a, @dptr
mo v r4, a
inc dptr ;на следующий элемент
cjne a, min_hi, cmphi ;сравним ст байт текущего со ст байтом минимального
jmp cmplow ;если равны, то сравнение мл байтов
cmphi: ;не равны
jnc next ;если текущий больше, то на следующий
jmp newmin ;если меньше, то сохраняем новый минимальный

cmplow: ;сравниваем мл байты
mov a, r3 ;мл байт текущего элемента
cjne a, min_lo, cmplo ;сравним мл байт текущего с мл байтом минимального
jmp next ;если равны, то на следующий
cmplo: ;не равны
jnc next ;если больше, то на следующий

newmin: ;нашли новый минимальный
mov min_adr_lo, work_adr_lo
mov min_adr_hi, work_adr_hi
mov min_lo, r3
mov min_hi, r4
next: ;переходим на анализ следующего элемента
djnz r2, loop ;циклим, пока r2 не ноль
pop dph
pop dpl
pop psw
pop acc
ret
eee:
end

Отправлен: 03.04.2011, 21:27
Вопрос задал: katbka (1-й класс)
Всего ответов: 1
Страница вопроса »


Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, katbka!
Программа сначала вводит данные через P0, ровно N слов: каждый байт по прерыванию INT1.
В порядке: младший первым
(порядок на старший первым менять не стал, т.к. приведенная подпрограмма рассчитана на младший первым )
Затем ищет минимальное слово и его адрес
По прерыванию INT0 передает 4 байта, адрес, значение (младший первым)
После чего программа опять идет на прием слов
Обратите внимание, что программа последовательно разрешает/запрещает прерывания
для отработки в каждый момент времени только одной операции.
Прерывания INT0, INT1 настроены на срабатывание по срезу (а не по уровню)
Изучайте

Код:
;По прерыванию INT1 ввести исходные данные через порт P0. 
;Выполнить подпрограмму (В массиве, состоящим из N 16-разрядных кодов,
;определить минимальный элемент и зафиксировать его адрес.
;Массив находится во внешнем ОЗУ ).
;По запросу INT0 вывести результаты через последовательный канал,
;работающий в режиме 1 программно на скорости 4800 бит\с.

Stack equ 60h ;адрес стека
Array equ 0000h ;адрес данных во внешней памяти
N equ 6 ;количество слов данных

arr_adr_lo equ 30h ;мл байт адреса массива
arr_adr_hi equ 31h ;ст байт адреса массива
arr_count equ 32h ;длина массива
min_adr_lo equ 33h ;мл байт адреса минимального элемента
min_adr_hi equ 34h ;ст байт адреса минимального элемента
min_lo equ 35h ;мл байт минимального элемента
min_hi equ 36h ;ст байт минимального элемента
work_adr_lo equ 37h ;мл байт адрес а текущего элемента
work_adr_hi equ 38h ;ст байт адреса текущего элемента

org 0
jmp start ;адрес старта программы

org 03h
jmp _int_0 ;адрес обработчика INT0

org 13h
jmp _int_1 ;адрес обработчика INT1

org 23h
jmp _serial ;адрес обработчика прерывания от посл. порта (бай передан)

org 28h
start:
;инициализация режимов работы
mov sp,#Stack ;назначение стека

mov scon,#01000000b ;Режим 1 последовательного порта,
;8 бит, изменяемая скорость
;прием запрещен, работаем только на передачу
mov tmod,#00100000b ;Режим 2 таймера T1,
;8-битный перегружаемый таймер/счетчик
mov th1,#0fah ;константа для таймера для задания скорости 4800 бод

mov tcon,#01000101b ;запуск таймера Т1 (tcon.6)
;INT1 по срезу (tcon.2)
;INT0 по срезу (tcon.0)

setb ea ;разрешаем прерывания (вообще)

loop: ;основной цикл
;ждем данные
mov a rr_adr_lo,#low Array ;подготавливаем регистры для приема данных
mov arr_adr_hi,#high Array
mov arr_count,#(N*2) ;счетчик байт (N - число слов)

setb ex1 ;разрешаем прерывание по INT1

wait_in: ;ждем, пока не примем ровно N слов
mov a,arr_count ;проверяем счетчик принятых байт
jz wait_in ; на 0 (уменьшается в прерывании INT1)

;данные приняты!
clr ex1 ;запрещаем прерывание INT1
call min ;обрабатываем

clr f0 ;сбросим флаг (в PSW) для контроля конца передачи
setb ex0 ;разрешаем прерывание INT0 (для инициализации передачи)

wait_out: ;ожидаем конца передачи
jnb f0,wait_out ;ждем бит (установится в прерывании от посл. порта)
jmp loop ;все сделано! - идем на начало

_int_1: ;прерывание INT1
push acc ;сохраним используемые регистры
push psw
push dpl
push dph
mov a,p0 ;принимаем байт из p0
mov dpl,arr_adr_lo ;адрес, куда надо писать
mov dph,arr_ adr_hi
movx @dptr,a ;сохраняем
inc dptr ;инкремент адреса
mov arr_adr_lo,dpl ;сохраняем адрес
mov arr_adr_hi,dph
dec arr_count ;уменьшаем счетчик
pop dph ;восстанавливаем регистры
pop dpl
pop psw
pop acc
reti ;выход из прерывания

_int_0: ;прерывание INT0
push acc
push psw
clr ex0 ;запрещаем прерывание INT0
setb es ;разрешаем прерывание от последовательного порта
mov r0,#min_adr_lo ;заносим адрес буфера, откуда будем отправлять данные
mov a,@r0 ;читаем первый байт
inc r0 ;инкремент адреса
mov sbuf,a ;отправляем на передачу
pop psw
pop acc
reti

_serial: ;прерывание от последоватеьного канала
push acc ;используем только по передаче байта
push psw
jnb ti,_serial_ret ;если не от передачи, то на выход
clr ti ;сбрасываем бит прерывания
cjne r0,#(min_hi+1),_serial_continue ;проверяем, дошли ли до конца данных на передачу
clr es ;все передано - запрещаем прерывание от посл. канала
pop psw
setb f0 ;взводим бит - все сделано!
pop acc
reti< br>_serial_continue: ;продолжаем передавать
mov a,@r0 ;очередной байт
inc r0 ;инкремент адреса
mov sbuf,a ;отправляем на передачу
_serial_ret:
pop psw
pop acc
reti

min: ;поиск адреса минимального элемента
mov dpl, #low Array ;адрес массива
mov dph, #high Array
mov min_lo, #0ffh ;min = 0ffffh
mov min_hi, #0ffh
mov r2, #N ;число элементов

min_loop:
mov work_adr_lo, dpl ;адрес текущего элемента
mov work_adr_hi, dph
movx a, dptr ;мл байт текущего элемента
mov r3, a
inc dptr ;на адрес ст байта
movx a, @dptr
mov r4, a
inc dptr ;на следующий элемент
cjne a, min_hi, cmphi ;сравним ст байт текущего со ст байтом минимального
jmp cmplow ;если равны, то сравнение мл байтов
cmphi: ;не равны
jnc next ;если текущий больше, то на следующий
jmp newmin ;если меньше, то сохраняем новый минимальный

cmplow: ;сравниваем мл байты
mov a, r3 ;мл байт текущего элемента
cjne a, min_lo, cmplo ;сравним мл байт текущего с мл байтом минимального
jmp next ;если равны, то на следующий
cmplo: ;не равны
jnc next ;если больше, то на следующий

newmin: ;нашли новый минимальный
mov min_adr_lo, work_adr_lo
mov min_adr_hi, work_adr_hi
mov min_lo, r3
mov min_hi, r4
next: ;переходим на анализ следующего элемента
djnz r2, min_loop ;циклим, пока r2 не ноль
ret

end

-----
Люби своего ближнего, как самого себя

Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 05.04.2011, 13:25
Номер ответа: 266560
Украина, Кировоград
Тел.: +380957525051
ICQ # 234137952
Mail.ru-агент: igorlyskov@mail.ru

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 266560 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Вопрос № 182729:

    Здравствуйте! Прошу помощи в следующем вопросе:
    Принять два числа по последовательному каналу: ввод программный, скорость 4800 бит.с, режим 1
    Выполнить сложение чисел
    В зависимости от запроса прерываняи INT0 или INT1 данные вывести побайтно через P0 или P1

    Отправлен: 05.04.2011, 04:16
    Вопрос задал: Labadist (Посетитель)
    Всего ответов: 1
    Страница вопроса »


    Отвечает Лысков Игорь Витальевич (Старший модератор) :
    Здравствуйте, Labadist!
    Вот Вам программа.
    Смотрите комментарии в тексте. Если непонятно, обращайтесь в мини-форум
    Код:
    ;Принять два числа
    по последовательному каналу: ввод программный, скорость 4800 бит.с, режим 1
    ;Выполнить сложение чисел
    ;В зависимости от запроса прерываняи INT0 или INT1 данные вывести побайтно через P0 или P1
    Stack equ 60h ;адрес стека
    Arg1 equ 30h ;первый аргумент
    Arg2 equ 31h ;второй аргумент
    Sum equ 32h ;сумма

    org 0
    jmp start ;адрес старта программы

    org 03h
    jmp _int_0 ;адрес обработчика INT0

    org 13h
    jmp _int_1 ;адрес обработчика INT1

    org 23h
    jmp _serial ;адрес обработчика прерывания от посл. порта (бай принят)

    org 28h
    start:
    ;инициализация режимов работы
    mov sp,#Stack ;назначение стека

    mov scon,#01010000b ;Режим 1 последовательного порта,
    ;8 бит, изменяемая скорость
    ;прием разрешен
    mov tmod,#00100000b ;Режим 2 таймера T1,
    ;8-битный перегружаемый таймер/счетчик
    mov th1,#0fah ;константа для таймера для задания скорости 4800 бод

    mov tcon,#01000101b ;запуск таймера Т1 (tcon.6)
    ;INT1 по срезу (tcon.2)
    ;INT0 по срезу (tcon.0)

    setb ea ;разрешаем прерывания (вообще)
    loop:
    mov r4,#2 ;число принимаемых байт
    mov r0,#Arg1 ;адрес, куда принимаем байты
    clr ri ;на всякий случай сбросим флаг принятого байта
    clr ex0 ;запретим прерывание INT0
    clr ex1 ;запретим прерывание INT1
    setb es ;разрешим прерывание от последовательного порта
    Wait:
    cjne r4,#0 ,Wait ;ждем, пока не примем 2 байта

    clr es ;запрещаем прерывание от посл.порта
    mov a,Arg1
    add a,Arg2
    mov Sum,a ;складываем
    clr f0 ;сбросим флаг, говорящий о том, что ответ выдан на порт
    setb ex0 ;разрешаем прерывания INT0, INT1
    setb ex1
    Wait_tr:
    jnb f0,Wait_tr ;ждем, когда байт будет выдан на порт
    jmp loop ;на повтор

    _int_0: ;отработка INT0
    push psw
    push acc ;сохраним регистры
    mov a,Sum
    mov p0,a ;выдаем сумму на p0
    pop acc
    pop psw
    setb f0 ;отработали
    reti

    _int_1: ;отработка INT1
    push psw
    push acc
    mov a,Sum
    mov p1,a ;выдаем сумму на p1
    pop acc
    pop psw
    setb f0 ;отработали
    reti

    _serial: ;посл. канал
    push psw
    push acc
    clr ri ;сбросим флаг прерывания
    mov a,sbuf ;забираем
    mov @r0,a ;сохраняем
    inc r0 ;инкрементируем адрес
    dec r4 ;уменьшаем счетчик
    pop acc
    pop psw
    reti

    end

    -----
    Люби своего ближнего, как самого себя

    Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
    Ответ отправлен: 05.04.2011, 14:16
    Номер ответа: 266565
    Украина, Кировоград
    Тел.: +380957525051
    ICQ # 234137952
    Mail.ru-агент: igorlyskov@mail.ru

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 266565 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Вопрос № 182735:

    Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:Помогите с программой под ОС Windows XP, TASM.Программу прокомментировать. Условия программы: Дана двухбайтовая двоичная строка. Найти в ней самую длинную группу подряд идущих единиц. Найти адрес группы и ее длину.

    Заранее Спасибо!!!

    Отправлен: 05.04.2011, 08:22
    Вопрос задал: Magma (Посетитель)
    Всего ответов: 1
    Страница вопроса »


    Отвечает Зенченко Константин Николаевич (Модератор) :
    Здравствуйте, Magma!

    Смотрите приложение.
    Нумерация бит с нуля. Выводится номер старшего бита последовательности и её размер. При одинаковых размерах последовательностей - выводистя младшай из них.
    Вопросы задавайте в мини-форум.
    Удачи!

    Приложение:

    -----
    Итерация от человека. Рекурсия — от Бога. — Л. Питер Дойч

    Ответ отправил: Зенченко Константин Николаевич (Модератор)
    Ответ отправлен: 05.04.2011, 12:46
    Номер ответа: 266556
    Украина, Киев
    Тел.: +38-097-238-60-03
    Адрес: Украина, Киев

    Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 266556 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.



    В избранное