Jump to content

    
Sign in to follow this  
Arlleex

Насколько умна директива EQU в Keil uVision?

Recommended Posts

Приветствую.

Решил прямо в .asm-файле сделать финт ушами вычислить некое арифметическое выражение с константами.

Имеется startup-файл, в котором определена таблица векторов прерываний

__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

                ; External Interrupts
                ...

 

Значения __initial_sp, Reset_Handler и остальные - константы, их реальные числовые значения становятся известны на этапе линковки.

Хочу определить макрос, делающий очень простые арифметические операции над этими константами, чтобы получить результирующее значение в виде одного числа.

Однако, даже простое суммирование, например

__MY_CALC_ADDR__    EQU    Reset_Handler + NMI_Handler

вызывает ошибку

Цитата

error: A1109E: Bad expression type

 

При этом само выражение (в примере Reset_Handler + NMI_Handler) использовать можно где-угодно, но я хотел заменить его одним именем...

 

Этому есть какое-то логичное объяснение?

Share this post


Link to post
Share on other sites

Конечно есть. Нужно прочитать описание директив компилятора armasm.exe - конкретно EQU.

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0100a/armasm_caccddic.htm

Share this post


Link to post
Share on other sites

Не вижу противоречий. Reset_Handler и прочие - константы.

Например,

__Vectors_Size  EQU  __Vectors_End - __Vectors

считает правильно, но это всего лишь метки (относительные адреса).

 

Мне казалось, что и символами Reset_Handler и пр. можно оперировать как угодно, что (почти) подтверждается правильной работой конструкции

__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     __initial_sp + Reset_Handler + NMI_Handler          ; <- + HardFault_Handler + ...
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

                ; External Interrupts

 

Мануал говорит, что это как #define в Си, однако если я эту сумму вынесу в EQU и подставлю в DCD символическое имя - будет ошибка.

Share this post


Link to post
Share on other sites
11 часов назад, Arlleex сказал:

Значения __initial_sp, Reset_Handler и остальные - константы, их реальные числовые значения становятся известны на этапе линковки.

Хочу определить макрос, делающий очень простые арифметические операции над этими константами, чтобы получить результирующее значение в виде одного числа.

Если хотя бы один из ISR, на которые ссылается таблица прерываний, определён в другом файле (а не в этом .asm), то указатель на него будет не константой. Он будет браться на этапе компоновки из таблиц экспорта .obj-файлов. А значит на этапе компиляции он неизвестен.

11 часов назад, Arlleex сказал:

Однако, даже простое суммирование, например


__MY_CALC_ADDR__    EQU    Reset_Handler + NMI_Handler

вызывает ошибку

Естественно. Чтобы так сделать надо все вектора из таблицы прерываний направить на метки внутри этого .asm-файла.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this