【问题标题】:A wrong size of "len" calculated by $ - symbol with FASM EQU [closed]使用 FASM EQU 的 $ - 符号计算的“len”大小错误 [关闭]
【发布时间】:2017-10-17 05:53:20
【问题描述】:

我有这个 FASM 代码:

  msg1:
      db "hello", 0

  msg1_len equ $ - msg1        ; should be 6

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

虽然msg1_len应该是6,但是我调试的时候,它返回了一个奇怪的大数,比如4570,即“msg1_len”等于4570

在其他应用程序中也是如此——一个看起来很随机的大数字,而不是字符串的长度。

这是为什么?如何解决?

【问题讨论】:

  • 您必须向我们展示尝试使用 msg1_len 的代码和/或您在调试器中使用的命令来显示该值。向我们展示您的完整代码会很有帮助。
  • 对我来说看起来是正确的,除非 msg1_lenmsg1 位于不同的部分。 (或者它和msg1之间还有其他非零大小的东西。)
  • @PeterCordes,同一部分,彼此相邻
  • FASM 手册 (flatassembler.net/docs.php?article=manual) 说$ 与 NASM 的工作方式相同,因此要么 FASM 有问题,要么您使用错误。停止拖钓我们并发布您用来获取价值的代码。试试mov eax, msg1_len,看看反汇编。 (和/或机器代码,记住 x86 立即数是 little-endian)。
  • 嘿,您在这里寻求帮助,无需对试图帮助您改善问题的人无礼。

标签: linux assembly x86 fasm


【解决方案1】:

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定义的位置。

【讨论】:

  • 所以equ 的作用类似于文本替换,并在使用msg1_size 的位置评估$?这可以解释 OP 获得的大量数据。哎呀,我想这个问题毕竟是可以回答的。
  • @PeterCordes 让我大吃一惊(因为我对 FASM 一无所知)。有时它有助于尝试重复 OP 的步骤(使用他们提供的有限信息),以确定他们的问题是否有一些优点。嗯,学习新东西永远不晚,尤其是如果你很快忘记东西,你基本上每天早上都可以学习新东西......(现在我要弄清楚那个叫“牙膏”的有趣管子有什么用)
  • 顺便说一句,您显然需要将equ 行放在使用它们的代码之前。我猜在 FASM 中,将数据和数字常量放在文件的底部是个好主意,因此如果您使用 equ 而应该使用 = 而不是出错,这是一个汇编时错误常数。
猜你喜欢
  • 2020-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
  • 2015-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多