Звучит как сумасшедшая вещь, но я полагаю, у вас есть на то веские причины.Жизнь без веселья без небольшого безумия.
Один из подходов, который вы можете использовать, - это использовать ассемблер во время сборки для генерации констант во время компиляции.
Первый шаг - сделатьфайл, содержащий каждую инструкцию по сборке, которую вы будете использовать, по одной на строку.
Например:
cmpwi 3,0x20
addi 3,3,0
blr
Назовите этот файл input.def.Затем используйте этот сценарий оболочки:
#!/usr/bin/env bash
(cat << HEADER
.global main
.text
main:
HEADER
cat input.def) > asm.s
powerpc-linux-gnu-as asm.s -o asm.o
powerpc-linux-gnu-objdump -d asm.o | \
sed '1,/<main>/ d' | \
paste -d'\t' - input.def | \
awk -F'\t' '{
bytes=$2
asm=$4
disasm=$3
gsub(/ /, "", bytes);
gsub(/[, ]+/, "_", asm);
printf("#define ASM_%-20s 0x%s // disassembly: %s\n", asm, bytes, disasm)
}'
# Clean temporaries
rm asm.s asm.o
(здесь я использую GNU-ассемблер и objdump. Возможно, вам придется изменить эту часть, если вы не используете эти инструменты. Objdump используется как прославленный hexdumpутилита здесь.)
Этот сценарий оболочки:
- Создает файл сборки
- Собирает его
- Помещает его рядом с input.def,(Это позволяет увидеть, какую сборку вы набрали.)
- Переформатирует гекс, чтобы он был допустимой константой Си.Переформатирует asm, чтобы он был допустимым символом C.Затем пишет определение для сопоставления имени инструкции с константой.
- Поместите все это в asm.h
Это большая работа, но вы можете сделать всево время компиляции.
Создает заголовочный файл с именем asm.h:
#define ASM_cmpwi_3_0x20 0x2c030020 // disassembly: cmpwi r3,32
#define ASM_addi_3_3_0 0x38630000 // disassembly: addi r3,r3,0
#define ASM_blr 0x4e800020 // disassembly: blr
Файл asm.h используется так:
#include "asm.h"
*((volatile int *)(0x80001234)) = ASM_cmpwi_3_0x20;
Есливам нужна новая константа asm, отредактируйте файл input.def и перезапустите сценарий оболочки.