Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

第三十七章:名字、标签与地址

复习

  • 汇编语言以 LOADADD 一类助记词代替难读的机器指令编码。
  • CPU 最终仍要面对真实的存储器地址。

TL;DR

  • 程序员可以用名字表示数据的位置,用标签表示一条指令的位置。
  • 名字和标签只在翻译时服务于人;CPU 执行时只看到地址。
  • 它们让程序插入、移动和阅读时不必逐个修改数字。

正文

  假设地址 20 放着苹果数,地址 21 放着梨数。下面这段程序可以工作:

LOAD A, [20]
LOAD B, [21]
ADD  R, A, B
STORE [22], R

  但三天后回来看,谁还记得 20、21 和 22 分别是什么?更麻烦的是,如果我们在程序开头多放一条指令,原先写死的跳转地址都可能偏移。数字地址是机器的需要,却不该成为人的负担。

  汇编语言允许我们这样写:

start:
    LOAD A, [apples]
    LOAD B, [pears]
    ADD  R, A, B
    STORE [total], R

apples: .byte 3
pears:  .byte 5
total:  .byte 0

  applespearstotal 是数据的名字start: 则是一个标签,它标在某条指令之前。以后若要跳回开头,就可以写 JMP start,不用猜第一条指令此刻位于地址 0、地址 4,还是别的地方。

  名字并没有住进 CPU 的寄存器里,也没有神奇地占据一块存储器。翻译程序时,工具会先算出 apples 实际被安排在何处,再把 LOAD A, [apples] 改写为带那个地址的机器指令。程序运行后,名字已经完成使命,留下的只有地址和位。

  这也让我们第一次看到程序的两部分:前面是会被依次执行的指令,后面是被指令读写的数据。它们都在存储器里,却承担不同角色。

  接下来还差关键一步:是谁收集这些名字,计算每个位置,并把整份汇编程序变成机器码?

思考题

如果 JMP start 前面新增两条指令,为什么通常不需要改写这句?

小结

知识点

  • 地址是机器定位内容的方式。
  • 符号名称表示数据位置,标签表示指令位置。
  • 翻译完成后,符号会被替换为相应地址。

参考资料

  • Randall Hyde,《汇编语言:基于 x86 处理器》

思考题答案(仅供参考)

  因为翻译工具会重新计算 start 所在的位置,并把新的地址填入跳转指令;人不必手工追踪偏移。

协议

本文采用 CC BY-NC-SA 4.0 协议发布。