Ревич, Ю.В. Программирование микроконтроллеров AVR: от Arduino к ассемблеру
142 Часть 11. Программирование микроконтроллеров АVR на ассемблере ЗАМЕТКИ НА ПОЛЯХ Обратите внимание, что путем такого формата можно адресовать максимум $FFFF+1 (65 536) адресов (наследие l пtel 8086, в котором память делилась на сегменты по 64 К) , т. е. охватить объем памяти программ в 1 31 072 байта ( 1 28 К) . Дnя контролле ров, содержащих больший объем памяти (ATmega2560) , этот адрес должен , очевидно, интерпретироваться как-то иначе. Мы не станем на этом останавливаться , т. к. на ассемблере вы никогда не напишете код такого объема, - просто запомните этот факт на всякий случай . В первой строке служебный байт типа данных равен 02 , и это означает, что данные в ней представляют сегмент памяти, с которого должна начинаться запись (в рас сматриваемом случае 0000) . Заканчивается НЕХ-файл всегда строкой : 00 0 0 0 0 0 1 FF значение типа данных 0 1 означает конец записи, данных больше не ожидается. А что означает FF'? Самым последним байтом в каждой строке идет контрольная сумма (дополнение до 2, иначе она называется LRC, Longitudinal Redundancy Check) всех остальных бай тов строки, включая служебные. Алгоритм вычисления LRC очень простой - нужно вычесть из числа 256 значений всех байтов строки (не обращая внимание на перенос) и взять младший байт результата. Соответственно, проверка целостности строки еще проще - нужно сложить значения всех байтов (включая контрольную сумму), и младший байт результата должен равняться нулю. Так, в первой строке число информационных байтов всего два, оба равны нулю, плюс (в начале) число информационных байтов, равное 2, плюс служебный байт типа данных, равный также 2, итого контрольная сумма всегда равна 256 - 2 - О - О - 2 = 252 = $FC. В последней строке одни нули, кроме типа данных, равного 1 , - соответственно, контрольная сумма равна 256 - 1 = 25 5 = $FF. Теперь попробуем немного расшифровать данные. Первое слово в первой инфор мационной строке, как мы выяснили, равно $СОЗА. Если мы возьмем фирменное описание команд, то обнаружим, что значению старшей тетрады в КОП, равной $С ( 1 1 00 в двоичной системе), соответствует команда rjmp - как мы знаем, практиче ски любая программа начинается с безусловного перехода на метку RESET. Теперь очевидно, что остальные биты в этом значении ( $ 0ЗА) представляют абсолютный адрес в программе, где в тексте стояла метка RESET. Попробуем его найти - для этого вспомним, что адреса отсчитываются по словам, а не по байтам, т. е. число $ ЗА (десятичное 5 8) нужно умножить на 2 (получится 1 1 6 = $ 7 4 ) и искать в этой об ласти. Разыщем строку с адресом $ 0 0 7 0, отсчитаем от начала шесть служебных бай тов, потом три слова (три пары байтов) от начала данных, и найдем там фрагмент FB 94 , который в нормальной записи будет выглядеть как $ 9 4 FB, а это, как легко убе диться по справочнику, есть код команды cli , запрещающей прерывания (которая в начале программы лишняя, т. к. они все равно запрещены, но, видимо, поставлена на всякий случай). Следующая команда будет начинаться с байта $Е5, и первая тет рада в ней обозначает код команды ldi ( 1 1 1 О - проверьте ! ), а пятерка, очевидно, есть фрагмент адреса конца памяти ( RAМEND ) , который в силу «зеркального» форма та записи получается на самом деле равным $ 0 2 5F (см. значение младшего байта, равное $2F). Это соответствует значению RAМEND, определенному в iпс-файлах для
Made with FlippingBook
RkJQdWJsaXNoZXIy MTExODQxMg==