Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Тема закрыта

AVR ASM RAM

Чт июл 05, 2012 22:52:23

Как можно прочитать и записать 'nm' элемент массива 'array' ?
num - номер элемента
Код:
.dseg
  array  :  .byte 80
  nm     :  .byte 1

Re: AVR ASM RAM

Чт июл 05, 2012 23:42:59

Код:
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 в массив

Re: AVR ASM RAM

Пт июл 06, 2012 06:23:54

Вот такой способ еще есть, но num не должно быть больше 63 ($3f)

Код:
ldi      YL, low(array)           ; заргузить адрес array в Y
ldi      YH, high(array)      

ldd      r16, Y+num               ; чтение из num
std      Y+num, r16               ; сохранение в num

Re: AVR ASM RAM

Сб июл 07, 2012 09:36:47

Вот такой способ еще есть


Хм. А прокатит? По-моему, такие конструкции

ldd r16, Y+num

вычисляются препроцессором.

Re: AVR ASM RAM

Сб июл 07, 2012 17:20:15

Ser60 писал(а):
Код:
ldi      XL, LOW(array)      ; заргузить адрес array в Х поинтер
ldi      XH, HIGH(array)      
lds      R16, num            ; загрузить индех в R16
add      XL, R16            ; вычислить адрес элемента в RAM
clr      R16
adc      XH, R16            ; Х = адрес
Если поискать по форуму, то несколько раз найдётся

viewtopic.php?p=726327#p726327
viewtopic.php?p=904128#p904128

Код:
lds     XL, num                ; загрузить индех в XL
clr     XH                     ; Подготовить XH к вычислениям
subi    XL, LOW( -array )      ; Вычесть минус_число это всё равно что прибавить плюс_число, младшая школа
sbci    XH, HIGH( -array )     ; Х = адрес


Меньше кода, меньше регистров занято.
Я сейчас опять скажу обидное, но любой вменяемый С-компилятор делает такой компактный код. Какой смысл на асме писать хуже?

_____
А вообще-то это так, ping. «Пользуясь случаем» Чтобы старина Джек не беспокоился :-)

Re: AVR ASM RAM

Сб июл 07, 2012 17:21:38

YS писал(а):Хм. А прокатит? По-моему, такие конструкции
ldd r16, Y+num
вычисляются препроцессором.
Ну да. Не покатит.
Точнее, num должно быть константой, вычисляемой ассемблером на этапе компиляции.

Re: AVR ASM RAM

Сб июл 07, 2012 22:29:42

Так по условию задачки он и есть константа. А вот код для задачки до конца так никто и не написал. :cry:

Re: AVR ASM RAM

Вс июл 08, 2012 01:17:42

ILYAUL писал(а):Так по условию задачки он и есть константа.

Если num константа, то решение - всего одна команда lds :))

Re: AVR ASM RAM

Ср июл 11, 2012 12:51:03

sx386 писал(а):Как можно прочитать и записать 'nm' элемент массива 'array' ?
num - номер элемента
Код:
.dseg
  array  :  .byte 80
  nm     :  .byte 1

для начала - nm в вышеприведенном не является элементом массива array :tea:
этот элемент объявлен как самостоятельная метка в ОЗУ - по сему запись и /или чтение из него возможно любым доступным способом, вполоть до:
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/)
:beer:

Re: AVR ASM RAM

Ср июл 11, 2012 22:31:04

этот элемент объявлен как самостоятельная метка в ОЗУ - по сему запись и /или чтение из него возможно любым доступным способом, вполоть до:
lds Rn, nm
sts nm,Rn ; где Rn любой из регистров (R0-R31)
а
Ошибочка , вышла :))) . Чем отличается nm от array - да собственно ничем. И тот и другой МАССИВ данных , только один содержит 80 байт , а второй всего лишь один. И оба имеют 16 битный адрес в области RAM/ Так как к ним можно и нужно обращаться?

Re: AVR ASM RAM

Чт июл 12, 2012 06:44:16

верно и то и другое - это ячейки в области ОЗУ
но под "массивом" подразумевается группа данных, размещенных в определенном порядке значения которых привязаны определенной зависимиостью к своему адресу...
обычно эти данные считываются/записываются выборочно
можно и напрямую (по абсмолютному адресу) - но тогда каждой ячейке свое имя задавать нужно...
причина - при задании вида (num - смещение относительно начала массива arrey)
ldi xl,low(arrey+num)
ldi xh,high(arrey+num)
или
lds Rn,arrey+num / sts arrey+num,Rn
получаем значения адреса ячейки, которые действительны исключительно на момент компиляции программного кода, а нужно чтоб этот адрес вычислялся программой в МК во время работы устройства то-ли в зависимости от внешних воздействий, то-ли в зависимости от результатов каких-либо вычислений 8)
несколько привычнее выглядят типовые таблички перекодировки для семисегментных индикаторов - тот же массив, но в ПЗУ и, в большинстве случаев, только для чтения (при записи ПЗУ свои особенности)
:beer:

Re: AVR ASM RAM

Чт июл 12, 2012 10:36:06

Я говорил немножко не об этом .
Из условия задачи , нужно забрать данные из ячейки массива array и поместить их в ячейку памяти в nm. Доступ к nm возможен только через индексные регистры X,Y,Z. А как это сделать - уже просто выбор программиста.

Re: AVR ASM RAM

Пт июл 13, 2012 06:17:30

как раз к nm доступ возможен любым способом - ее адрес фиксирован и вроде изменениям по ходу выполнения программы не подлежит...
поэтому допустимо обращение как через индексные регистры, так и прямая адресация и/или с помощью указателя стека (push/pop)
только обмен через стек требует повышенного внимания к подпрограммам и прерываниям 8)

Re: AVR ASM RAM

Пт июл 13, 2012 06:50:37

Вообще-то адрес ячейки nm не столь важен и при обращении к ней можно его "забыть".
Тема закрыта