Доступ к глобальной переменной дает нежелательные значения

Я пытался напечатать переменные через UART со следующим кодом на C.

Процессор - Intel 80486

Компилятор - IC компилятор (от Intel, выпущенный в 1990 году)

uint32_t unGlobal = 0xABCDEF90;

void main (void)
{
    uint32_t unLocal = 0x12345678;

    UartWrite (unLocal);
    UartWrite (unGlobal);
}

UartWrite () - драйвер последовательного порта. Аргумент UartWrite является 32-битным, и внутри он печатает каждый символ.

Здесь локальная переменная печатается правильно, но печать глобальной переменной дает ненужные значения! В чем может быть причина не получить значение глобальной переменной. Может кто-то помочь мне с этим?

3 ответа

Решение

Проблема была со статической инициализацией. Потому что повторная инициализация глобальной переменной во время выполнения дает правильное значение. Спасибо, рэйкер, @Lundin и все

Тип аргумента в прототипе для UartWrite может быть недостаточного размера, чтобы содержать значение для вашей глобальной переменной. У меня нет прототипа, но для похожих функций (без сомнения, для разных библиотек) тип аргумента char, Если это также char в вашем прототипе, а затем передать значение для unsigned int будет вероятным источником вашей проблемы.

Следующее иллюстрирует сценарий, в котором функция будет принимать переменную размера, слишком большую для прототипа, без ошибок, но затем может дать неожиданные результаты:

int func(char a)
{
    a = 10000;
    return a;
}

int main(void)
{
    int a = 10000;
    int b;
    b = func(a);// note int type, or 10000 does not fit into a char type
                // b is returned, but not with the expected value.
    printf("%d" b);
    return 0;
}

результаты: b = -24

Опубликовать прототип для UartWrite (??? );

РЕДАКТИРОВАТЬ (новая информация)

Я нашел этот документ Intel на компиляторе, выпущенном в 1990 году, который может быть родственником того компилятора, который вы используете. Посмотрите на разделы, начиная со страницы 68:

Каждое глобальное определение символа или ссылка в модуле компиляции имеет атрибут видимости, который управляет тем, как (или если) на него можно ссылаться извне компонента, в котором он определен. Существует пять возможных значений видимости:
• EXTERNAL - компилятор должен обрабатывать символ, как если бы он был определен в другом компоненте. Для определения это означает, что компилятор должен предполагать, что символ будет переопределен (прерван) определением того же имени в другом компоненте. См. Преобразование символа. Если символ функции 69 имеет внешнюю видимость, компилятор знает, что он должен вызываться косвенно, и может встроить заглушку косвенного вызова.
• ПО УМОЛЧАНИЮ - другие компоненты могут ссылаться на символ. Кроме того, определение символа может быть переопределено (прервано) определением того же имени в другом компоненте.
• ЗАЩИЩЕНО - другие компоненты могут ссылаться на символ, но он не может быть заменен определением того же имени в другом компоненте.
• HIDDEN - другие компоненты не могут напрямую ссылаться на символ. Однако его адрес может передаваться другим компонентам косвенно (например, в качестве аргумента вызова функции в другом компоненте или путем сохранения его адреса в ссылке на элемент данных функцией в другом компоненте).
• ВНУТРЕННИЙ - на символ нельзя ссылаться вне его определяющего компонента, ни прямо, ни косвенно.

Чуть дальше вниз Например:

int i __attribute__ ((visibility("default")));
void __attribute__ ((visibility("hidden"))) x () {...}
extern void y() __attribute__ ((visibilty("protected");  

Там намного больше. Надеюсь это поможет.

Ключевое слово volatile указывает на то, что "значение может изменяться между различными доступами, даже если оно не изменяется". Попробуйте это и посмотрите, работает ли это для вас.

Другие вопросы по тегам