Почему этот указатель массива сдвинут на 1?

Я готовлюсь к экзамену по микропроцессорам, и возник такой примерный вопрос:

вопрос

Таким образом, после кода в памяти программы есть массив:

array: .db 11,12,13,14,15,16,17,18,19,20

и в коде указатель загружается как:

ldi ZL, low(array<<1);

Мой вопрос в том, почему этот сдвиг на 1 присутствует в коде, который мне дали. На мой взгляд, метка «массив» должна указывать прямо на байт памяти, содержащий число 11. Если я правильно понимаю, сдвиг влево на 1 умножит на 2. Не отбросит ли это его далеко? Мне дали неверный код или я чего-то не понимаю?


person nickhansenrf    schedule 13.12.2019    source источник
comment
См. также этот ответ, особенно примечание о avr-as.   -  person Jester    schedule 13.12.2019
comment
Включите достаточно кода в фактический вопрос, чтобы это имело смысл, а не только как часть изображения. Очевидно, ключ в том, что мы хотим использовать Z в качестве указателя для lpm (загрузить память программы) вместо обычной памяти данных.   -  person Peter Cordes    schedule 13.12.2019
comment
@Jester: Это похоже на дубликат (*2 совпадает с <<1, сделано по той же причине lpm). Я не понимаю, почему такое поведение может быть полезным; корректно ли работают метки для меток в разделах данных? Или есть что-то еще, что вы можете сделать с адресами меток, где вы хотите, чтобы они были разделены на 2?   -  person Peter Cordes    schedule 13.12.2019
comment
Кстати, текстовая часть решения на изображении неверна. Это не 0x01010101 (32-битное шестнадцатеричное число), а 0b01010101 (8-битное двоичное число). В исходном коде это правильно: 0x55. И да, x & mask == mask — это то, как вы проверяете, установлены ли все интересующие вас биты. (Возможно, вы могли бы сделать это более эффективно, добавив константу, которая устанавливает флаг переноса, если все биты маски установлены, иначе нет. Тогда используйте adc вместо перехода через inc)   -  person Peter Cordes    schedule 13.12.2019


Ответы (1)


Из описания LPM:

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

Таким образом, сдвиг выполняется для преобразования адреса слова в адрес байта.

person Michael    schedule 13.12.2019
comment
Думаю, я понял... так как память программы адресована в 16-битном делении, в ней только половина адресуемых слов по сравнению с тем, если бы она была адресована байтами... так что умножение на 2 направляет LDI в правильное место в программной памяти, потому что предполагается, что все адресовано байтами. - person nickhansenrf; 13.12.2019