Цитата(barabek @ Dec 11 2008, 03:31)

Если две функции не могут вызываться одновременно (случай с прерыванием) - то конечно же пусть они используют одни и те же адреса для локальных переменных. В этом и соль этих переменных в отличии от глобальных. Если посмотреть на листинг то почти в каждой функции для локальных переменных используются регистры. И это очень хорошо, это только плюс компилятору-линкеру. Ведь памяти очень немного

Добрый день.
Спасибо всем за ответы.
Все что Вы ранее высказывали, я прекрасно понимаю.
Но тут вещь в следующем.
Компилятор никогда не отображает локальные переменные на одни и теже адреса, если они пересекаются при вызове процедур (РАЗНЫХ ПРОЦЕДУР). Если переменные пересекаются (отображаются на одни и теже адреса) (РЕГИСТРЫ НАПРИМЕР), то компилятор при входе в такую процедуру сохраняет все эти регистры в стек. Если компилятор этого не делает - то это плохой компилятор. Анализирую код Keil'а он (Кейл) именно так и делает. Если я в перерывании (или процедуре) использую вызов процедуры, то в прерывании, перед ее выполнением, сохряняются все регистры и PSW в стек. Если я неиспользую каких либо регистров (ну компилятор в процессе компиляции ничего не задействовал), то на входе он ничего не сохраняет. Для Кейла я это проверял. Правда весь листинг виден только в самом проце, в выходных файлах этого нет.
В данном примере происходит все именно так.
Если у меня есть ряд процедур, которые могут вызваться из прерывания и у них есть локальные переменные, то компилятор не отражает на адреса этих переменных ничего из других процедур.
В данном примере я заметил пересекающиеся области (две ячейки наложились. Две ячейки локальных переменных разных процедур). Причем ячеки входящих переменных (извиняюсь за корявость, но переменных через которые я передаю данные в процедуру).
Есть функция Spi_RD в которую я передаю ряд параметров. Она
вызывается в прерывании.
Есть функция Filtrate_long в которую я передаю одно число и в нутри нее есть переменные счетчики.
Так пересеклись две переменные из входящих переменных функции Spi_RD и внутренние переменные-счетчики процедуры Filtrate_long.
На примере других функций я вижу, что используемые регистры для локальных переменных в процедурах, компилятор сохраняет в стек, при вызове внутри одной процедуры другой (с такими же регистрами). Иначе я вообще никогда не смог бы вызывать внутри процедур другие процедуры. Именно так происходит и тут. Просто количество параметров передаваемых в процедуру Spi_RD наверное большое и они вышли за регистры и компилятор о них забыл (мое предположение).
Вот вызовы процедур с которыми я нашел пересечение переменных:
Код
bit Spi_RD(byte * ptr, byte * complete, word LEN, byte type, byte FIRST_SENT, bit cs);
signed long filtrate_long(signed long input_data);
Пересеклись адреса следующих переменных
type, FIRST_SENT с локальными переменными (счетчиками) внутри функции Filtrate_long.
В данный момент локальные переменные функции Filtrate_long я объявил в области XDATA дабы они попросту ушли из карты памяти в другую область (остальные вроде как ен пересекаются). И все работает без глюков.
Без наездов. Просто пытаюсь разобраться, что я делаю не так. И что мне следует сделать, чтобы такого не происходило впредь.
Ведь я не исключаю того что такое же может произойти в области XDATA.
Цитата(tag @ Dec 11 2008, 13:05)

Как известно памяти у 51 немного, плюс компилятор разработан так что локальные переменные сохраняет не на стеке, а либо в регистрах, либо в памяти (в этом вы можете убедится просмотрев руководство). В случае когда переменные располагаются в памяти линковщик может перекрывать область памяти локальных переменных одной подпрограммы и такую же область другой подпрограммы. Видимо так сделано с целью экономии памяти. Тогда, конечно подразумевается что эти фукции к примеру, не могут вызывать друг друга из своего тела. Так линковщик работает если ему не указать опцию nooverlay. Когда данная опция указана области локальных переменных подпрограмм не пересекаются и следовательно проблема порчи локальных переменных исчезает.
Добрый день.
Огромное вам спасибо.
Мне кажется - это есть лекарство моей болезни. Так как симптомы вы описали точно.
Черт, а ведь эта директива относится ко всему проекту. С ней области data не хватает

А для лечения локально, нужно делать глобальбные переменные. А что же делать с входыми данными процедур??? Тоже глобально??