这将是非常具体的,但我很好奇。我有一个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
。为什么它在这里组装而不是在前一种情况下?
2条答案
按热度按时间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字节。myss37ts2#
我也有类似的问题。我使用预处理器和
%define
指令: