来自不同文件的 EQU 出现“尝试在 BSS 空间中保留非常量”错误

问题描述 投票:0回答:2

这将是非常具体的,但我很好奇。 我有一个 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
    将常数与标签关联起来,那么为什么会出现这个错误呢?
  2. 如果是 B.asm 的以下 BSS 部分
t1          resb 1
t2          resb (1*nodeNum + 1*nodeNum)
treevptr    resd 1

它组装没有错误,但

nodeNum
为0,所以
t1+1
变得与
treevptr
相同。 为什么它在这里组装而不是在前一种情况下组装?

assembly nasm extern
2个回答
0
投票

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

%定义 BUFFLEN1 500

...

.bss 部分

我的缓冲区:resb BUFFLEN1


0
投票

符号“地址”(在本例中实际上只是一个值)

nodeNum
只是一个链接时间常数,而不是汇编时间。但 NASM 为此需要一个汇编时间常量,因为对于从一个 .asm 文件生成的内容,布局需要固定
1

您应该

%include
您的
equ
定义,而不是尝试使用链接器。
(也许将常量移动到单独的
.asm
.h
,其中只有
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 字节。

© www.soinside.com 2019 - 2024. All rights reserved.