【问题标题】:What is the purpose of the assembler and symbol table? What is at a symbol's address?汇编器和符号表的目的是什么?符号的地址是什么?
【发布时间】:2019-09-18 03:27:02
【问题描述】:

来自我的教科书:

要生成汇编语言程序中每条指令的二进制版本,汇编器必须确定所有标签对应的地址。汇编器跟踪符号表中分支和数据传输指令中使用的标签。如您所料,该表包含成对的符号和地址。

为什么需要符号表?如果我们有一个带有标签名称和地址的符号表,地址有什么用?地址是什么...只是标签的名称?还是标签上的说明?

假设我们在汇编 MIPS 中有这样的指令:

add_numbers:
   addi, $s0, $t0, 2

为什么符号表不只存储add_numbers | <the_binary_representation_of_the_instruction> 而不是add_numbers | <address_location_of_label>

【问题讨论】:

  • 因为到该标签的分支需要地址,而不是存储在那里的指令的编码。
  • 您混淆了汇编语言和机器代码。处理器只知道机器码,它基本上是一组数字。它不知道名称或标签。机器代码中的所有内容都必须以数字形式完成,也就是位串。通常,这些数字是相对于某物(例如当前指令或寄存器)的距离。名称和标签是汇编语言,与机器代码对应(它们用于计算处理器将理解的距离/数字),但它们处于不同的级别。
  • 结果是机器码。那是一系列字节值。它必须驻留在计算机的某个地方,通常在内存中。并且内存可以按字节寻址,因此您可以在地址 0、1、2、... 有一些字节。示例的结果是指令 addi 的机器代码。 “add_numbers:”标签不产生机器代码,它只是addi指令的第一个字节存储在内存中的地址的书签,仅在编译时对汇编程序可用。所以它会记住符号表中的书签并使用它来计算针对它的跳转/分支指令的正确机器代码

标签: assembly mips


【解决方案1】:

标签是地址,它是程序员向汇编程序提供地址但不必知道物理地址的一种方式。让工具链为您完成这项工作。

我不记得我的 MIPS 手头了,所以这里有一些伪代码。

loop_top:
   nop
   nop
   sub r0,1
   cmp r0,0
   bne loop_top

取决于指令集,但通常条件分支将是 pc 相关的。通常在组装过程中使用的表格在表格上进行一次或多次传递将解析分支与目的地之间的距离,以便可以对分支进行完整编码。上述大多数指令集都可以一次性解决。 loop_top 是一个带有地址的标签,但是对于这里的分支来说,它是 pc 相关的,你不需要知道物理地址。

但是

   call my_fun

一旦通过代码,汇编器发现 my_fun 没有在这个文件中定义和/或汇编语言有一些语法在使用之前将它标记为外部。无论哪种方式,它都是外部的。组装此文件时无法解析。因此需要表来指示标签名称,以及该指令在该对象中的位置,取决于汇编器,它可能暂时将临时偏移量或完整地址填充为零,或者将其编码为无限循环。

链接器稍后确定处理器内存空间中事物的实际地址,链接器最终将拥有一个表,其中包含所有(工具链此阶段的相关标签)标签及其在链接时的地址,然后链接器将返回进入代码并修复/创建此调用指令的机器代码,因为它知道该标签的实际地址是什么。

j hello

对象:

Disassembly of section .text:

00000000 <.text>:
   0:   08000000    j   0x0
   4:   00000000    nop

另一个对象:

.globl hello
hello:
    j hello

.word hello

链接他们

Disassembly of section .text:

00001000 <_ftext>:
    1000:   08000402    j   1008 <hello>
    1004:   00000000    nop

00001008 <hello>:
    1008:   08000402    j   1008 <hello>
    100c:   00000000    nop
    1010:   00001008    0x1008

作为对象,所有工具链必须继续使用标签 hello 作为稍后解析的地址。在这种情况下,在链接时,链接器通过对象工作,计算字节数,形成标签及其地址的表。在第一次或其他一些过程中,它将根据需要更改指令或数据以解析这些标签。

现在老式的汇编器从同一个源文件进行汇编和链接工作,声明“汇编器必须确定与所有标签对应的地址”。执行链接器工作的通常不是具有常用工具链的汇编器。因此,引用的声明可以使用一些改进。但希望这表明标签是地址,它们代表一个尚未确定的地址,因此代码比这样的代码更容易编写

  nop
  nop
  j pc-2

那么如果你添加另一个指令

  nop
  add r0,r1
  nop
  j pc-3

或者

   j 0x1008

然后必须花费大量时间重写程序以将每个地址硬编码到程序中。添加/删除一行,并且必须更改许多其他代码。代表地址的标签使这一切变得更加容易,工具链确定地址,然后返回并用地址替换标签......

添加了一个 nop:

Disassembly of section .text:

00001000 <_ftext>:
    1000:   08000403    j   100c <hello>
    1004:   00000000    nop
    1008:   00000000    nop

0000100c <hello>:
    100c:   08000403    j   100c <hello>
    1010:   00000000    nop
    1014:   0000100c

如果我们没有标签并且不得不硬编码地址,那么您将不得不更改这三个位置作为 nop 的结果。一条线。如果你添加了几十行,数百行。你将如何跟踪这一切?通过在 cmets 中放置标签?一遍又一遍地组装、拆卸和修补源代码,直到它看起来有点正确,并希望没有错误。

mips-elf-readelf -s so.elf

Symbol table '.symtab' contains 14 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00001000     0 SECTION LOCAL  DEFAULT    1 
     2: 00400000     0 SECTION LOCAL  DEFAULT    2 
     3: 00400018     0 SECTION LOCAL  DEFAULT    3 
     4: 00000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000a010     0 NOTYPE  LOCAL  DEFAULT    2 _gp
     6: 00002018     0 NOTYPE  GLOBAL DEFAULT    4 _fdata
     7: 0000100c     0 OBJECT  GLOBAL DEFAULT    1 hello
     8: 00001000     0 NOTYPE  GLOBAL DEFAULT    1 _ftext
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _start
    10: 00002018     0 NOTYPE  GLOBAL DEFAULT    2 __bss_start
    11: 00002018     0 NOTYPE  GLOBAL DEFAULT    2 _edata
    12: 00002018     0 NOTYPE  GLOBAL DEFAULT    2 _end
    13: 00002018     0 NOTYPE  GLOBAL DEFAULT    2 _fbss

这是一个有趣的:

     7: 0000100c     0 OBJECT  GLOBAL DEFAULT    1 hello

标签 hello 一旦组装并链接到最终二进制文件中,就等于地址 0x100C。

【讨论】:

  • 是的,MIPS 有 PC 相关的条件分支。它的跳转指令是半绝对的,取代了PC的低28位。 MIPS 没有 FLAGS 寄存器(而是使用 bne r1, r2, targetbgez r1, target 之类的指令),但幸运的是,这与您的示例无关。
  • 顺便说一句,您可能想说“绝对地址”或“最终地址”而不是“物理地址”。启用或禁用分页与此无关,只是为具有单个 asm 源文件的分支提供便利,或者链接器如何为目标文件之间的分支工作。
  • 是的,很公平,正在寻找与地址一起使用的正确词。
猜你喜欢
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
  • 2011-05-24
相关资源
最近更新 更多