gpt4 book ai didi

linux - 使用 FASM EQU 通过 $ - 符号计算出错误的大小 "len"

转载 作者:太空宇宙 更新时间:2023-11-04 04:44:22 25 4
gpt4 key购买 nike

我有这个 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 文档:

The = directive allows to define the numerical constant. It should be preceded by the name for the constant and followed by the numerical expression providing the value. The value of such constants can be a number or an address, but - unlike labels - the numerical constants are not allowed to hold the register-based addresses. Besides this difference, in their basic variant numerical constants behave very much like labels and you can even forward-reference them (access their values before they actually get defined).

2.3.2 Symbolic constants :

The symbolic constants are different from the numerical constants, before the assembly process they are replaced with their values everywhere in source lines after their definitions, and anything can become their values.

The definition of symbolic constant consists of name of the constant followed by the equ directive. Everything that follows this directive will become the value of constant. If the value of symbolic constant contains other symbolic constants, they are replaced with their values before assigning this value to the new constant.

结论:因此您应该使用 = 而不是 equ(在 FASM 中)。

(我的意思是计算数字常量..您仍然可以使用 equ 来表示符号常量...对我来说听起来像宏定义)

您得到了大常量,因为您在代码之前定义了该符号,并且在编译期间它执行了类似于 mov edx,$ - msg1 的操作,其中 $ 已经是指令的地址,而不是您放置的 msg1_len 定义。

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com