Ассемблер g cc и тип переменной (длина, знак) - PullRequest
2 голосов
/ 30 мая 2020

Я использую компилятор m68k-elf-as (https://gnutoolchains.com/m68k-elf/) для кода сборки, который я вставляю в ЭБУ своего автомобиля (CPU32 ISA, процессор MC68376).

Есть ли простой способ управления приведением типов в ассемблере GNU? У меня проблемы со знаком данных и длиной.

Вот примеры моих проблем

1) Знак: я использую инструкцию быстрого перемещения, которая принимает 8 бит немедленных данных, знак- расширяет его и помещает в регистр данных:

MOVEQ #136,%D0

, и ассемблер жалуется: «Ошибка: несоответствие операндов - оператор moveq # 136,% D0 'ignored' Это компилируется, только если я напишу два дополнение: 'MOVEQ # -120,% D0'

Я понимаю, что значение в D0 содержит знак, поэтому негибкая интерпретация этой инструкции требует, чтобы я записал 8-битное значение со знаком, но конечное использование То, что находится в реестре в моем коде, продиктовано последующими инструкциями. т.е. моя следующая инструкция действует с 8-ми битами данных, и я использую значение как беззнаковое. биты - это биты.

Есть ли простой способ заставить компилятор .as принимать любое записанное мной 8-битное значение вместо исключения чего-либо на основе предположения о значении со знаком?

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

MOVE.W 0x6(%PC,%D0.W),%D0 |code prior to this makes sure that D0 contains an even value <=18
JMP 0x2(%PC,%D0.W)   
jump_start:
.word end_routine-jump_start    | this does not compile correctly
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word end_routine-jump_start
.word continue_routine-jump_start  |if D0 contains 18, then we continue in the routine
BRA.W end_routine
continue_routine:

При компиляции метка jump_start находится по адресу 0x31072, а end_routine адрес находится по адресу 0x314e0, поэтому встроенные данные должны быть: 0x046e, что легко вписывается в 16-битную директиву .word, которую я написал. Однако компилятор не может правильно вычислить это, если я не использую директиву .long.

Есть ли простой способ заставить компилятор вычислить значение, используя необходимые 32-битные, а затем преобразовать или замаскировать его до 16 бит, сохраняя при этом данные встроенной таблицы переходов?

еще одна вещь: я явно добавил команду «всегда ветвиться» в конец данных в таблице переходов, но затем компилятор добавляет больше строк аналогичного характера:

BRA.W $456 |branch to end_routine, added by me
BRA.W $e   |branch to continue_routine, added by compiler
BRA.L $a   |branch to continue_routine, added by compiler
BRA.L $448 |branch to end_routine, added by the compiler
continue_routine:

Есть ли простой способ заставить компилятор не добавлять лишний код? Я уже избегаю компиляции через .g cc перед использованием .as из-за дополнительного кода, который он добавляет ...

...