问题描述
我有以下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
最终(?)更新:
检查FASM文档有关 2.2.1数值常数:
vs 2.3.2符号常量:
结论:因此,您应该使用=
代替equ
(在FASM中).
(用于计算数值常量,我的意思是..您仍然可以将equ
用作符号常量...对我来说听起来像是宏定义)
之所以有一个大常量,是因为您在代码之前定义了该符号,并且在编译过程中它做了类似mov edx,$ - msg1
的操作,其中$
已经是指令的地址,而不是您放置的msg1_len
定义./p>
I have this FASM code:
msg1:
db "hello", 0
msg1_len equ $ - msg1 ; should be 6
Then later in code, mov edx, msg1_len
puts its value in a register.
Although msg1_len is supposed to be 6, when I'm debugging it, it returns a strange big number such as 4570. that is, "msg1_len" is equal to 4570
In other applications it's same -- a big, random-looking number instead of the length of a string.
Why is this? How to fix it?
TL:DR: in FASM, equ
is a text substitution, like NASM %define
.
FASM len = $ - msg1
evaluates once, on the spot. (Like equ
in most other assemblers, and also like =
in MASM and GAS).
Text substitution breaks because $ - msg1
is context-sensitive: $
is the current position so mov edx, $ - msg1
is some large size that depends on the position of the instruction. equ
would be fine for something like 8 * myconst
in most cases.
EDIT: ooops.... I did use =
, not equ
.
When I replaced =
with equ
, I get compile error:
helloworld.asm [13]:
mov edx,msg1_size ; Length of message
error: undefined symbol 'msg1_size'.
(flat assembler version 1.71.51)
Works for me, when I put it into compilable FASM example, I get 6
.
The full code I used to verify it works correctly:
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
^^ this compiles as mov edx,6
, verified in debugger.
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
final(?) update:
Check FASM docs about 2.2.1 Numerical constants:
Conclusion: so you should use =
instead of equ
(in FASM).
(for calculating numeric constants I mean.. you can still use equ
for symbolic constants... sounds to me like macro definition)
You got your big constant because you had that symbol defined ahead of code, and during compilation it did something like mov edx,$ - msg1
, where $
is already address of the instruction, not your placement of msg1_len
definition.
这篇关于尺寸错误的"len"表示由$-用FASM EQU符号计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!