【问题标题】:Assembly and Execution of Programs - Two pass assembler [closed]程序的汇编和执行 - 两遍汇编器[关闭]
【发布时间】:2016-11-30 18:48:07
【问题描述】:

在阅读一本关于机器指令和程序的书时,我遇到了一个特殊的点,它说汇编程序会扫描整个源程序两次。它在第一次通过/扫描期间建立一个符号表,并在第二次扫描期间将整个程序与它相关联。汇编器需要以类似的方式为函数提供地址。
现在,既然汇编程序要通过程序两次,为什么要声明一个函数才能使用呢?汇编器不会从第一遍为函数提供地址,然后在第二遍期间将其与程序相关联吗? 在这种情况下,我正在考虑 C 编程。

【问题讨论】:

  • 函数需要在什么汇编器中声明才能使用?
  • C 编译器不是汇编程序。 C 语言的规则与汇编程序的工作方式无关。
  • 我的意思是,要“汇编”的编译程序需要为程序包含的每个函数、变量等正确定义。如果汇编程序必须运行程序两次,不需要声明函数吗?
  • 您混淆了编译器和汇编器。它们不是一回事。
  • 第二遍只需要解析(fixup)前向引用。它甚至不需要完全通过源,只需通过参考列表即可。 IIRC Borland 编译器组使用类似的技术来实现“编译器”的 Turbo 应变。

标签: c assembly machine-instruction


【解决方案1】:

简单的答案是,C 程序要求在使用函数之前先声明函数,因为 C 语言被设计为由编译器一次性处理。它与汇编程序和函数地址无关。编译器需要知道符号的类型,无论是函数、变量还是其他东西,才能使用它。

考虑这个简单的例子:

int foo() { return bar(); }
int (*bar)();

为了生成正确的代码,编译器需要知道bar 不是函数,而是指向函数的指针。代码只有在 foo 的定义之前放置 extern int (*bar)(); 才有效,这样编译器就知道 bar 是什么类型。

虽然该语言在理论上可以设计为要求编译器使用两次传递,但这将需要对该语言的设计进行一些重大更改。需要两次通过也会增加编译器所需的复杂性,减少可以托管 C 编译器的平台数量。这在 C 语言最初被开发的那一天是非常重要的考虑,当时 64K (65,536) 字节的 RAM 是很多内存。即使在今天,也会对大型程序的编译时间产生显着影响。

请注意,通过支持隐式函数声明,C 语言确实允许你想要的东西。 (在我上面的示例中,当 bar 之前未声明时,foo 中会发生什么。)但是,此功能已过时、有限且被认为是危险的。

【讨论】:

    猜你喜欢
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 2014-12-26
    相关资源
    最近更新 更多