Вызов процедур сборки из исходного кода c в keil ide

У меня есть процедуры задержки для микроконтроллера 8051 на языке ассемблера. Я могу использовать их в программах на языке ассемблера, но я хочу использовать эти процедуры на языке c, поскольку они создают идеальную задержку для меня.

Код для задержки, который является файлом delay.asm, я отправляю только ниже...

;ALL DELAYS ROUTINES HERE
DELAY_SEG SEGMENT CODE
RSEG DELAY_SEG
;DELAY OF 1MS SUBROUTINE
DELAY1MS:
     MOV R7,#250
     DJNZ R7,$
     MOV R7,#247
     DJNZ R7,$
     RET
;DELAY OF 100MS SUBROUTINE
DELAY100MS:
     MOV R6,#99;1MUS
L1:
     ACALL DELAY1MS ;99MS
     DJNZ R6,L1;198MUS
     MOV R6,#250;1MUS
     DJNZ R6,$;500US
     MOV R6,#147;1US
     DJNZ R6,$;294US
     NOP
     RET;1US
;DELAY 0F 1SEC SUB ROUTINE
DELAY1S:
     MOV R5,#9
L2:
     ACALL DELAY100MS
     DJNZ R5,L2
     MOV R5,#99
L3:
     ACALL DELAY1MS
     DJNZ R5,L3
     MOV R5,#250
     DJNZ R5,$
     MOV R5,#138
     DJNZ R5,$
     RET

Я включаю этот код на ассемблере и использую просто. Но я хочу вызвать эти подпрограммы из исходного кода c.

2 ответа

Решение

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

  • присвойте модулю то же имя, что и имя файла без расширения (я предполагаю, что у вашего исходного файла есть имя delays.a51):
MODULE DELAYS
  • перед каждым именем функции, которое вы хотите видеть в модулях C, ставьте подчеркивание.

  • для каждой функции нужно объявить отдельный сегмент кода с
    следующее соглашение об именах:

? PR? FunctionName? ModuleName

  • поместите каждую функцию в отдельный сегмент.
  • также каждое имя функции должно быть сделано PUBLIC

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

?PR?_DELAY1MS?DELAYS    SEGMENT CODE
    RSEG        ?PR?_DELAY1MS?DELAYS
    PUBLIC      _DELAY1MS
_DELAY1MS:
    ...
    ...
    RET

Чтобы сделать функции доступными для компилятора C, вы должны объявить их без каких-либо искажений (без подчеркивания), поэтому для DELAY1MS у вас есть:

void Delay1ms(void);

Все эти сложные игры с именами и сегментами требуются для компоновщика, поскольку он строит график вызовов для статического выделения памяти для локальных переменных во время соединения.

Я не знаю, как работает интерфейс между вашим ассемблером и вашим компилятором C, но обычно вы должны указать ассемблеру экспортировать функции (для этого должна быть директива, посмотрите руководство по ассемблеру). Обычно функции в ассемблере должны иметь подчеркивание перед именем, например _DELAY1S, Тогда вам нужно создать extern объявление в исходном коде со ссылкой на функцию, например

extern void DELAY1S(void);

Это может отличаться для ваших инструментов, прочитайте документацию.

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