微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

“警告:.bss 部分:对齐 2**32 不可表示”在 GNU 汇编器中是什么意思?

如何解决“警告:.bss 部分:对齐 2**32 不可表示”在 GNU 汇编器中是什么意思?

使用 MinGW-w64 附带的 GNU Assembler 版本组装由我的编译器生成的 x86 汇编代码会产生以下警告:

E:/MinGW32/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/../../../../i686-w64-mingw32/bin/ld.exe: analogClockForWindows.exe: warning: section .bss: alignment 2**32 not representable

这是什么意思?最让我疑惑的是汇编代码根本没有提到.bss
不知道有没有关系,但是CygWin自带的GNU Assembler版本和TDM自带的版本-GCC 甚至拒绝组装我的代码,并给出大量错误消息。
我的编译器生成的汇编代码可在此处获得:https://github.com/FlatAssembler/ArithmeticExpressionCompiler/files/6446315/analogClockForWindows.s.zip

编辑:我只是使用 gcc -o analogClockForWindows analogClockForWindows.s 编译 my compiler 生成的汇编代码

更新:我认为这是触发该警告的最小示例:

.text
.comm   output,7360,32
.global _main
_main:
movl    $0,%eax
ret

解决方法

https://sourceware.org/binutils/docs/as/Comm.html#Comm

当使用 ELF 或(作为 GNU 扩展)PE 时,.comm 指令采用可选的第三个参数。这是符号所需的对齐方式,对于 ELF 指定为字节边界(例如,16 的对齐方式意味着地址的最低有效 4 位应为零),而对于 PE 指定为 2 的幂(例如,对齐 5 表示对齐到 32 字节边界)。

ELF 是 Linux 上使用的可执行格式,PE 是 Windows 上使用的。因此,对于 ELF (Linux),.comm output,7360,32 请求将 output 对齐到 32 字节边界,这很好。但是对于 PE (Windows),相同的指令被解释为要求 2**32 字节对齐,这是不可能的。在 Windows 上,您应该改为编写 .comm output,5

我不知道为什么这些不同;可能是为了与其他不同的汇编器兼容。

您可能需要向编译器添加一个标志以在 Windows 和 Linux 之间进行选择,以便可以为每种情况输出正确的指令。

,

这可能意味着您使用了 .align 32,它被解释为 .p2align(2 的幂)而不是 .balign(字节)。

在定位支持明确指令的 GAS 时,切勿使用歧义 .align 指令


在您的情况下,对齐出现在第三个参数 .comm 中,以在 BSS 中定义全局变量。像 .align 一样,解释依赖于目标,当为 Windows 组装时,这意味着您要求它通过 2**32(或 4GiB)对齐,ld 不处理.

(为 i386-elf-linux 组装时,表示按 32 对齐,2**5,按预期工作。)

the GAS manual 中所述:

当使用 ELF 或(作为 GNU 扩展)PE 时,.comm 指令采用可选的第三个参数。这是符号所需的对齐方式,将 ELF 指定为字节边界(例如,16 的对齐方式意味着地址的最低有效 4 位应为零),并且 对于 PE 为 2 的幂(例如,5 对齐表示对齐到 32 字节边界)。

对齐必须是绝对表达式,并且必须是2的幂。如果 ld 为公共符号分配了未初始化的内存,它会在放置符号时使用对齐方式。

如果没有指定对齐方式,as会将对齐方式设置为小于或等于符号大小的最大2的幂,在ELF上最多为16,或者在PE上默认为4的部分对齐方式

不幸的是,没有可移植的明确语法方式来使用它。您可以省略可选的第三个参数并使用默认对齐方式。

或者您可以改为使用 .bss 指令切换到 BSS 部分并使用 .spacelabel: 后保留空间。

或者只是不使用任何全局变量,并将结果保留在 st0 中。如果您在堆栈中使用 args,则不需要任何变量来评估表达式的全局变量。如果 x87 寄存器用完,您最多可以使用堆栈空间。或者,您可以引用全局变量,但将定义留给其他编译单元(例如,执行输入/输出的调用方。)

另外,result 真的需要 7360 字节吗?您的编译器 (https://flatassembler.github.io/compiler.html) 只使用 [result],而不使用 [result + reg]+ constant

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。