Closed. This question is off-topic。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
                        
                        2年前关闭。
                                                                                            
                
        
我有以下FASM代码:

  msg1:
      db "hello", 0

  msg1_len equ $ - msg1        ; should be 6


然后在代码后面,mov edx, msg1_len将其值放在寄存器中。

尽管msg1_len应该是6,但在调试时,它会返回一个奇怪的大数字,例如4570。也就是说,“ msg1_len”等于4570

在其他应用程序中,它是相同的-看起来很随机的大数字,而不是字符串的长度。

为什么是这样?如何解决?

最佳答案

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定义。

关于linux - 用FASM EQU由$-符号计算的“len”大小错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46783331/

10-10 14:15