2013-03-02 2 views
1

Профессор хотел бы, чтобы мы запрограммировали часть программы, используя ассемблерный код, а затем он хотел бы, чтобы мы назвали этот код из программы C, а затем вернемся к программе C, когда она будет завершена. Кажется, я не могу найти документацию. Я использую плату Dragon12, которая использует 68HC12, если это имеет значение. Не похоже, что он хочет, чтобы мы использовали встроенную функцию asm().Как вызвать код сборки из файла C в CodeWarrior?

+0

Звучит так, как будто он хочет, чтобы вы написали свой код сборки, чтобы использовать соглашение о вызове C для своей платформы, чтобы вы могли объявить его как внешнюю функцию в своей программе на C. – Neil

+0

Существует замечательная техническая заметка по этому вопросу, вы должны иметь ее где-то в своей установке Codewarrior в формате pdf. В противном случае выполните поиск на сайте Freescale. – Lundin

ответ

1

Вы можете вызвать функцию, определенную в сборке, как любую нормальную функцию на C (при условии, что вы используете правильное соглашение о вызове), просто убедитесь, что тип возвращаемого значения и аргументы совпадают. Например, если сборка выглядит следующим образом:

my_func: 
    ; assembly code here 
    ; some more assembly code 
    ; etc. 
    xor ax, ax 
    ret 

Тогда вы можете вызвать его из C следующим образом:

extern int my_func(); 

// ... 
int zero = my_func(); 
-1

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

0

Меню справочная документация для CodeWarrior Development Studio 10.5 описывает, как назвать чистые функции ассемблера внутри C код/​​C++ следующим образом:

метки, заданные в файле сборки имеют локальную область видимости. Чтобы получить доступ к ним из другого файла (файл .c), они должны быть помечены как глобальные. Например, .global _my_asm_func.

Для иллюстрации приведем пример фрагмент кода:

.global _my_asm_func 
.text 

_my_asm_func: 
    subq.l #4,a7 
    move.l d1,(a7) 
    add.l (a7),d0 
    addq.l #4,a7 
    rts 

В вашем C код/​​C++, сначала объявить прототип функции. Например, int my_asm_func(int a, int b);. Затем вызовите эту функцию, как и любую другую функцию C/C++. Например, my_asm_func(5, 2);.

Обратите внимание, что в коде сборки функция имеет префикс с подчеркиванием, но в C/C++ это не так. Я не уверен, что это требуется, или просто соглашение.

Параметры передаются в последовательные регистры данных. В этом случае вы ожидаете найти 5 в D0 и 2 в D1.

0

Вопрос давно, но ответ может по-прежнему помогать.

Для Kinetis MCU и gcc, , возможно, следующий фрагмент может проиллюстрировать возможность. (Это было частью моего обработчика ошибок) Ниже в прерывании PE_ISR используется встроенный ассемблер для вызова функции FaultHandlerAsm , которая, в свою очередь, также является встроенным ассемблером. В конце он переходит в c-функцию «faultHandlerC», которая здесь не включена.

void FaultHandlerAsm(void) 
{ 
    __asm volatile (
    " movs r0,#4  \n" 
    " movs r1, lr  \n" 
    " tst r0, r1  \n" 
    " beq _MSP   \n" 
    " mrs r0, psp  \n" 
    " b _HALT   \n" 
    "_MSP:    \n" 
    " mrs r0, msp  \n" 
    "_HALT:    \n" 
    " ldr r1,[r0,#20] \n" 
    " b FaultHandlerC \n" 
    //" bkpt #0   \n" 
); 
} 

PE_ISR(Cpu_INT_Hard_FaultInterrupt) 
{ 
    __asm( " b FaultHandlerAsm \n"); 
} 
Смежные вопросы