Jump to content

    

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

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

Решил прямо в .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

Не вижу противоречий. 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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this