Delphi汇编常量'eof'

10

在asm块上下文中似乎有一个未记录的常量eof。这是使用Delphi 7进行测试的。

program TestEof;
{$APPTYPE CONSOLE}
var
  example : Integer;
begin
  asm
    mov example, eof
  end;
  writeln(example);
  readln;
end.

这会打印出14

eof常量及其值$0E或者14来自哪里呢?


编辑:这是编译结果。

...
call @InitExe
// mov example, eof
mov [example], $0000000e
// writeln(example)
mov eax, [$004040a4]
mov edx, [example]
call @Write0Long
call @WriteLn
call @_IOTest
// readln;
...
1个回答

5

Eof 实际上是 System 单元中定义的函数

在我手头的 Delphi 实现中,包括 Delphi 6 和 XE2,Eof 被实现为一个 内置例程,会调用以下适当的函数之一:

function _EofFile(var f: TFileRec): Boolean;
function _EofText(var t: TTextRec): Boolean;

我不知道为什么你的汇编代码变成了mov [...],$0000000e。你在评论中指出,System单元本身在asm代码中使用了eof,例如在TextOpen中。在XE2中,相同的代码现在是纯Pascal,并搜索$1A的值,而不是$0E。这似乎是一项实现细节。如果你想理解为什么会这样,我认为你需要反向工程System单元中的代码,或者看看Embarcadero的工程师是否能向你解释实现细节。

严格来说,它是一个内置函数。内置函数调用rtl助手,这些助手函数由您指定,但也可以生成代码并调用其他函数(例如iotest)。EOF可能是内置函数的一些内部序列号,以帮助简化多个类似的内置函数(例如所有IOCheck/IOTest内置函数),但没有编译器源代码就只能猜测了。 - Marco van de Voort
@DavidHeffernan 如果您查看 TextOpen 函数的 Windows 版本,那么在遇到这个字符后文件将被截断。Linux 版本使用的是 cEOF,也就是 $1A - Egon
@DavidHeffernan 主要是出于好奇心,以及因为TextOpen截断了文件。所以基本上我知道了它被截断的原因,但我无法弄清楚为什么它应该编译成那个值$0E,而不是$1A - Egon
1
David,EOF(十六进制1A,十进制26)自DOS早期以来就意味着EOF。它是标准的文件结束字符,并且(很久以前 - 在DOS 5之前,如果我没记错的话)在文本文件中需要用来指示文件实际停止的位置。它在任何标准ASCII表中都被记录为EOF。例如,如果您使用GExperts,请查看他们的ASCII图表。如果您在Win7的命令提示符中使用copy con test.txt,您可以输入一行文本,然后按F6插入EOF字符,就像您在早期的DOS版本中所做的那样。 - Ken White
1
@Andreas 这就是你在Windows上终止交互式Python解释器的方式,不是吗?谁会用^N关闭输入流呢? - David Heffernan
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接