TL:DR:在 FASM 中,equ 是文本替换,类似于 NASM %define。
FASM len = $ - msg1 评估一次,当场。 (就像大多数其他汇编程序中的 equ,也像 MASM 和 GAS 中的 =)。
文本替换中断,因为 $ - msg1 是上下文相关的:$ 是当前位置,所以 mov edx, $ - msg1 是一些较大的大小,取决于指令的位置。在大多数情况下,equ 适用于 8 * myconst 之类的内容。
编辑:哎呀....我确实使用了=,而不是equ。
当我将= 替换为equ 时,出现编译错误:
helloworld.asm [13]:
mov edx,msg1_size ; Length of message
error: undefined symbol 'msg1_size'.
(平面汇编器版本 1.71.51)
对我有用,当我将其放入可编译的 FASM 示例中时,我得到 6。
我用来验证它是否正常工作的完整代码:
format ELF executable 3
entry start
;================== code =====================
segment readable executable
;=============================================
start:
mov eax,4 ; System call 'write'
mov ebx,1 ; 'stdout'
mov ecx,msg1 ; Address of message
mov edx,msg1_size ; Length of message
^^ 编译为mov edx,6,在调试器中验证。
int 0x80 ; All system calls are done via this interrupt
mov eax,1 ; System call 'exit'
xor ebx,ebx ; Exitcode: 0 ('xor ebx,ebx' saves time; 'mov ebx, 0' would be slower)
int 0x80
;================== data =====================
segment readable writeable
;=============================================
msg1:
db 'hello', 0
msg1_size = $-msg1
最终(?)更新:
查看有关 2.2.1 Numerical constants 的 FASM 文档:
= 指令允许定义数值常数。它的前面应该是常量的名称,后面是提供值的数值表达式。此类常量的值可以是数字或地址,但 - 与标签不同 - 不允许数字常量保存基于寄存器的地址。除了这种差异之外,在它们的基本变体中,数值常量的行为非常类似于标签,您甚至可以对它们进行前向引用(在它们实际定义之前访问它们的值)。
与2.3.2 Symbolic constants:
符号常量与数值常量不同,在汇编过程之前,它们在定义之后的源代码行中到处都被替换为它们的值,任何东西都可以成为它们的值。
符号常量的定义由常量名和equ 指令组成。遵循该指令的所有内容都将成为常量的值。如果符号常量的值包含其他符号常量,则在将此值分配给新常量之前,将它们替换为它们的值。
结论:因此您应该使用= 而不是equ(在FASM 中)。
(我的意思是计算数字常量..您仍然可以将equ 用于符号常量...听起来像宏定义)
你得到了你的大常量,因为你在代码之前定义了那个符号,并且在编译期间它做了类似mov edx,$ - msg1的事情,其中$已经是指令的地址,而不是你在msg1_len定义的位置。