第三十七章:名字、标签与地址
复习
- 汇编语言以
LOAD、ADD一类助记词代替难读的机器指令编码。 - 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
apples、pears、total 是数据的名字。start: 则是一个标签,它标在某条指令之前。以后若要跳回开头,就可以写 JMP start,不用猜第一条指令此刻位于地址 0、地址 4,还是别的地方。
名字并没有住进 CPU 的寄存器里,也没有神奇地占据一块存储器。翻译程序时,工具会先算出 apples 实际被安排在何处,再把 LOAD A, [apples] 改写为带那个地址的机器指令。程序运行后,名字已经完成使命,留下的只有地址和位。
这也让我们第一次看到程序的两部分:前面是会被依次执行的指令,后面是被指令读写的数据。它们都在存储器里,却承担不同角色。
接下来还差关键一步:是谁收集这些名字,计算每个位置,并把整份汇编程序变成机器码?
思考题
如果
JMP start前面新增两条指令,为什么通常不需要改写这句?
小结
知识点
- 地址是机器定位内容的方式。
- 符号名称表示数据位置,标签表示指令位置。
- 翻译完成后,符号会被替换为相应地址。
参考资料
- Randall Hyde,《汇编语言:基于 x86 处理器》
思考题答案(仅供参考)
因为翻译工具会重新计算 start 所在的位置,并把新的地址填入跳转指令;人不必手工追踪偏移。
协议
本文采用 CC BY-NC-SA 4.0 协议发布。