assembly “尝试在BSS空间中保留非恒定数量”错误,EQU来自不同文件

0s0u357o  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(77)

这将是非常具体的,但我很好奇。我有一个A.asm文件和一个B.asm文件。
在A.asm中有:

global nodeNum

section .data
; reading consts
cmdNum          equ 9
cmdSize         equ 5
; tree consts
nodeNum         equ 8

在B.asm中:

extern nodeNum

section .bss
t1          resb 1
t2          resb 5*nodeNum
treevptr    resd 1

组装此错误会导致“尝试在BSS空间中保留非常量数量”错误。
我的问题是:
1.为什么?伪命令equ将常量与标签关联,那么为什么会出现此错误?
1.在B.asm的以下BSS部分的情况下

t1          resb 1
t2          resb (1*nodeNum + 1*nodeNum)
treevptr    resd 1

它的组合没有错误,但nodeNum是0,所以t1+1变成了treevptr。为什么它在这里组装而不是在前一种情况下?

mnowg1ta

mnowg1ta1#

符号“address”(在本例中实际上只是一个值)nodeNum只是一个链路时间常数,而不是链路时间常数。但是NASM需要一个时间常数,因为对于从一个.asm文件生成的内容,布局需要固定。

你应该%include你的equ定义,而不是试图使用链接器。(也许移动常数到一个单独的.inc.mac,只有equ%define,和/或宏的东西,所以你可以包括它在多个其他文件。)

这也将使NASM将add ecx, nodeNum优化为3字节的add r/m32, imm8,而不是6字节的add r/m32, imm32:当它不能看到常量的实际数值时,它会为链接器留下最大的空间来填充它。因为一个小的数可以有很多位,但是一个大的数不能有太少的位。(此外,extern符号通常 * 是 * 32或64位值的实际地址。
脚注1:可能没有一个重定位类型允许链接器扩展可变数量的零。如果有ELF .o文件,NASM不支持它。如果在同一个.asm中定义了两个符号(例如,在你试图做的事情的任何一侧),NASM将它们之间的距离视为一个时间常数,例如。对于像mov eax, foo - bar这样的东西来填充一个数值作为汇编时间,或者众所周知的times 510-($-$$) db 0,它需要知道有多少字节已经被发送到当前部分,所以它可以填充到510字节。

myss37ts

myss37ts2#

我也有类似的问题。我使用预处理器和%define指令:

%define BUFFLEN1  500

...

section .bss

my_buffer:  resb BUFFLEN1

相关问题