首页 > 解决方案 > gcc 的汇编器和变量类型(长度、符号)

问题描述

我正在使用“m68k-elf-as”编译器 ( https://gnutoolchains.com/m68k-elf/ ) 来编译我正在修补到汽车 ECU(CPU32 ISA、MC68376 处理器)中的汇编代码。

有没有一种简单的方法来控制 gnu 汇编器中的类型转换?我在数据符号和长度方面遇到问题。

这是我的烦恼的例子

1) 符号:我使用一个快速移动指令,它获取 8 位立即数数据,对其进行符号扩展,并将其放入数据寄存器中:

MOVEQ #136,%D0

并且汇编器抱怨'错误:操作数不匹配-语句'moveq#136,%D0'被忽略'这只有在我编写二进制补码时才能编译:'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:

有没有一种简单的方法可以让编译器不添加额外的代码?我已经避免在使用 .as 之前通过 .gcc 进行编译,因为它添加了额外的代码......

标签: gccassembly68000gnu-toolchain

解决方案


推荐阅读