ldi XL, LOW(array) ; заргузить адрес array в Х поинтер ldi XH, HIGH(array) lds R16, num ; загрузить индех в R16 add XL, R16 ; вычислить адрес элемента в RAM clr R16 adc XH, R16 ; Х = адрес
ld R16, X ; чтение элемента array в R16 st X, R16 ; запись R16 в массив
ldi XL, LOW(array) ; заргузить адрес array в Х поинтер ldi XH, HIGH(array) lds R16, num ; загрузить индех в R16 add XL, R16 ; вычислить адрес элемента в RAM clr R16 adc XH, R16 ; Х = адрес
Если поискать по форуму, то несколько раз найдётся
lds XL, num ; загрузить индех в XL clr XH ; Подготовить XH к вычислениям subi XL, LOW( -array ) ; Вычесть минус_число это всё равно что прибавить плюс_число, младшая школа sbci XH, HIGH( -array ) ; Х = адрес
Меньше кода, меньше регистров занято. Я сейчас опять скажу обидное, но любой вменяемый С-компилятор делает такой компактный код. Какой смысл на асме писать хуже?
_____ А вообще-то это так, ping. «Пользуясь случаем» Чтобы старина Джек не беспокоился
_________________ Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Хм. А прокатит? По-моему, такие конструкции ldd r16, Y+num вычисляются препроцессором.
Ну да. Не покатит. Точнее, num должно быть константой, вычисляемой ассемблером на этапе компиляции.
_________________ Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Как можно прочитать и записать 'nm' элемент массива 'array' ? num - номер элемента
Код:
.dseg array : .byte 80 nm : .byte 1
для начала - nm в вышеприведенном не является элементом массива array этот элемент объявлен как самостоятельная метка в ОЗУ - по сему запись и /или чтение из него возможно любым доступным способом, вполоть до: lds Rn, nm sts nm,Rn ; где Rn любой из регистров (R0-R31) если же надо считать элемент массива array (0-80), то его надо объявлять как константу или лучше использовать содержимое указателя позиции (num), размешенного по адресу, находящемуся в ячейке nm - но так "мудрить" стоит только при нехватки оперативных регистров иначе удобнее было бы объявить : .undef XL ; только у avrasm2 !!! .undef XH ; только у avrasm2 !!! .def nm_arreyl=R26 .def nm_arreyh=R27 .def tmp=r17 .def nm=R16 ; R0-R15 только в случае, если не предусматривается непосредственная загрузка данных в регистр иначе доступно лишь R16-R31 .def adr_arreyl=r3 .def adr_arreyh=r4 .dseg array : .byte 80 ну и при инициализации записать какое-то начальное значение в nm и записать базовый адрес начала массива в какую-нибудь регистровую пару (а не напрямую в индексные регистры!) затем чтение/запись по предварительно модифицированному индексному регистру ( но ни базовый адрес ни содержимое указателя при этом изменяться не должны) можно конечно и другой вариант присобачить - нечто с базовым адресом в виде константы ( экономия двух регистров ) - но диапазон смещения маловат будет, посему с двумя дополнительными регистрами интереснее (да и число элементов массива может быть двухбайтовым...): clr nm ; на этапе инициализации ldi tmp,low(arrey) mov adr_arreyl,tmp ldi tmp,high(arrey) mov adr_arreyh,tmp
---------- mov nm_arreyl,nm clr nm_arreyh add nm_arreyl, adr_arreyl adc nm_arreyh,adr_arreyh ; создать текущий адрес элемента массива ну и дальше - читай или записывай (ld Rd,X /st X,Rd) ... только вот куда? (надо бы какой -то регистр назначения иметь /Rd/)
Карма: 15
Рейтинг сообщений: 70
Зарегистрирован: Ср мар 28, 2012 21:45:24 Сообщений: 906 Откуда: ВО
Рейтинг сообщения:0
Цитата:
этот элемент объявлен как самостоятельная метка в ОЗУ - по сему запись и /или чтение из него возможно любым доступным способом, вполоть до: lds Rn, nm sts nm,Rn ; где Rn любой из регистров (R0-R31)
а Ошибочка , вышла . Чем отличается nm от array - да собственно ничем. И тот и другой МАССИВ данных , только один содержит 80 байт , а второй всего лишь один. И оба имеют 16 битный адрес в области RAM/ Так как к ним можно и нужно обращаться?
верно и то и другое - это ячейки в области ОЗУ но под "массивом" подразумевается группа данных, размещенных в определенном порядке значения которых привязаны определенной зависимиостью к своему адресу... обычно эти данные считываются/записываются выборочно можно и напрямую (по абсмолютному адресу) - но тогда каждой ячейке свое имя задавать нужно... причина - при задании вида (num - смещение относительно начала массива arrey) ldi xl,low(arrey+num) ldi xh,high(arrey+num) или lds Rn,arrey+num / sts arrey+num,Rn получаем значения адреса ячейки, которые действительны исключительно на момент компиляции программного кода, а нужно чтоб этот адрес вычислялся программой в МК во время работы устройства то-ли в зависимости от внешних воздействий, то-ли в зависимости от результатов каких-либо вычислений несколько привычнее выглядят типовые таблички перекодировки для семисегментных индикаторов - тот же массив, но в ПЗУ и, в большинстве случаев, только для чтения (при записи ПЗУ свои особенности)
Карма: 15
Рейтинг сообщений: 70
Зарегистрирован: Ср мар 28, 2012 21:45:24 Сообщений: 906 Откуда: ВО
Рейтинг сообщения:0
Я говорил немножко не об этом . Из условия задачи , нужно забрать данные из ячейки массива array и поместить их в ячейку памяти в nm. Доступ к nm возможен только через индексные регистры X,Y,Z. А как это сделать - уже просто выбор программиста.
как раз к nm доступ возможен любым способом - ее адрес фиксирован и вроде изменениям по ходу выполнения программы не подлежит... поэтому допустимо обращение как через индексные регистры, так и прямая адресация и/или с помощью указателя стека (push/pop) только обмен через стек требует повышенного внимания к подпрограммам и прерываниям
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения