为何汇编代码采用寄存器间接寻址而非绝对寻址加载内存值?
关于Hamacher通用汇编中寻址方式选择的疑问
以下是Hamacher等人《Computer Organization and Embedded Systems》(第6版)中调用字节列表比较子程序MEMCMP的准备代码片段:
Move R2, #N Load R2, (R2) Move R3, #FIRST Move R4, #SECOND Call MEMCMP ...
背景信息:内存地址N存储列表条目数$n$,两个待比较列表的首元素分别位于地址FIRST和SECOND。
我的疑问聚焦于Move R2, #N和Load R2, (R2)这一指令序列:为何要通过两次指令(寄存器间接寻址)实现,而非直接使用Load R2, N(绝对寻址)?作者反复采用这种写法,我猜测可能与绝对寻址的地址无法装入指令有关,但未在书中找到答案。需明确的是,我清楚N等会被汇编器替换为对应内存地址的数值,仅对这种寻址方式的选择原因存在疑问。
这是因为该通用汇编对应的指令集架构(ISA)可能没有支持直接绝对寻址的Load指令格式——也就是指令长度不足以容纳完整的内存地址。
很多经典ISA(比如早期的RISC或者一些嵌入式架构)的指令是固定长度的(比如16位或32位),如果要把一个完整的内存地址(比如32位)塞进一条指令里,要么指令长度不够,要么需要额外的扩展方式。而用Move R2, #N先把地址N的数值(也就是内存地址常量)加载到寄存器,再用Load R2, (R2)通过寄存器间接寻址读取N地址里的实际值,是更通用的做法:
Move指令通常支持立即数寻址,这里的#N是汇编器替换后的地址常量,只要这个常量能放进Move指令的立即数字段,就能执行;- 后续的寄存器间接寻址只需要寄存器里的地址,不需要在指令里再塞大地址,适配大多数固定长度指令集的设计。
另外,这种写法也有兼容性和一致性的考虑:如果全书统一用这种方式加载内存中的数据,不管地址长度如何变化,代码模式都保持一致,方便读者理解寻址方式的本质,而不用纠结不同指令格式的特殊情况。
内容的提问来源于stack exchange,提问作者EE18
相关产品推荐
相关产品推荐

