2014-02-01 4 views
3

процессора: 8051 на основеКак переписать этот код asm в C?

следующие строки кода будет установлено значение 0xaa по адресу 0x0aaa во внешней флэш-памяти.

mov  a,#0aah 
mov  dptr,#X0aaa 
movx @dptr,a 

Ниже мы

Команда MOV позволяет передавать данные между любым внутренним I-RAM и местом, SFR и между аккумулятором внутренней пространствами I-RAM или местами SFR.

и MOVX и описание команд от CPU спецификации

инструкция MOVX используется для доступа к внутренней X-RAM и электронной FLASH области. Можно использовать только косвенную адресацию. Выбор заключается в том, следует ли использовать однобайтовый адрес, @Ri, где Ri может быть либо R0, либо R1 выбранного банка регистров , либо двухбайтового адреса, @DPTR.

CPU datasheet

Некоторый код, который я видел в примерах:

xdata UCHAR * data ecFlashaaa = (xdata UCHAR *)(0xaaa); 
*ecFlashaaa = 0xaa; 

код не компилируется, потому что он не знает, что это xdata, а также путать на data. Так почему-то мне нужно объяснить компоновщик, что ecFlashaaa указывает на e-Flash ...

+0

Есть ли у вас правильный компилятор? Вы включили правильные файлы заголовков? – Shahbaz

+0

Да, у меня есть. Сам пример неисправен. В моем проекте включен файл 'XCL', который определяет сегменты. '-D_XDATA_START = 8000 // Первый адрес xdata memory.',' -D_XDATA_Z_START = _XDATA_START \t // Первый адрес на чипе XDATA memory.' и т. Д., Но я не уверен, что там определен e-Flash , Даже если определено, как я могу привязать свою переменную к e-Flash. – Pablo

+0

Я действительно не знаю микро, поэтому я не знаю деталей, но если компилятор не понимает 'xdata' (в то время как ключевое слово существует в таблице данных), моя лучшая догадка - либо неправильный компилятор, либо отсутствующий заголовочный файл. – Shahbaz

ответ

1

Разница между образцом кода:

xdata UCHAR * data ecFlashaaa = (xdata UCHAR *)(0xaaa); 
*ecFlashaaa = 0xaa; 

И принял ответ, что с xdata компилятор будет генерировать код, очень похожий на вашей сборки snipet. Литеральное значение 0xaa будет записано в поле 0xaaa во внешнем ОЗУ (или в вашем случае, что, по-видимому, является EEPROM с отображением памяти во внешнем пространстве оперативной памяти) в нескольких инструкциях.

Принятый ответ с объявленным общим указателем unsigned char *flashptr будет использовать 3-байтовый тип для flashptr, где верхний байт укажет, в каком месте памяти находится адрес.Поэтому вместо того, чтобы объявляться как указатель на xdata, он объявляется как общий указатель, а затем присваивается значение как {XDATA, 0x0AAA}. Доступ к общим указателям осуществляется путем вызова библиотечной процедуры, которая использует правильную инструкцию (mov, movc или movx) для доступа к памяти.

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

(пример кода вы обнаружили, что я привел, вероятно, написана для C51 компилятора Keil в)

3

Данные и xdata - это, возможно, расширения или макросы компилятора (определенные в файле заголовка), которые соответствуют типу данных.

Написание кода на C довольно просто. Но независимо от того, генерирует ли он ассемблер, вы хотите, зависит от того, насколько интеллектуальный ваш компилятор. Знает ли он о различных типах памяти в вашей системе?

Что вы хотите сделать, это объявить указатель на байт, а затем установить значение указателя (а не то, на что оно указывает) на адрес, к которому вы хотите получить доступ. Затем вы можете разыменовать указатель и установить его на нужное значение.

unsigned char *flashptr = (unsigned char *)0xaaa; 
*flashptr = 0xaa; 

Это в значительной степени то, что у вас есть в примере, без дополнительных данных/xdata.

Смежные вопросы