MASM中的向前引用(Forward Reference)
当程序需要引用尚未定义的变量或标号时,编译器会如何处理呢,这就涉及到向前引用(Forward Reference)的概念。
一、Forward Reference的概念
程序引用到之前尚未定义的变量(Variable)、标号(Label)、段(Segment)或其他标识符(Symbol),编译器会如何处理?MASM编译器对源码执行两遍扫描,编译器第一遍会假设该引用的类型,为该类型留出存储空间,然后在第二遍将该引用的地址或数据填充正确。
这里就会产生2个问题:
1、编译器假设的类型与实际类型不一致,会导致预留的空间太大或太小,太大会使程序变大或导致执行效率降低,太小则无法正常编译通过。如jmp target,target默认假设为near,编译器预留空间为3个字节;但实际target为far,则需要5个字节。
2、编译器在处理前置引用时会降低编译效率,因此尽量不要发声向前引用。
二、向前引用标号(Label)
jmp target;Forward Reference ... ... target:
1、指令跳转,编译器会假设jmp为near jmp,如果jmp是short或far,需要明确指定,如far ptr。
2、子程序调用,编译器会假设call myproc为near(无论子程序是通过proc还是label的方式定义),如果proc定义为far,则需明确指定类型:call far ptr myproc。
3、如果标号为外部extrn引入,则不需要指定类型,直接jmp target或call myproc即可。
三、向前引用变量(Variable)
1、变量引用无论是否为向前引用,都需要明确类型,只是数据段寄存器无法确定。编译器会假设段寄出去为:DS,可通过段前缀进行指定:ES:myvar。
2、如果是segname:myvar或groupname:myvar的引用形式,且该段也未提前定义,则需将段加入到某个组(group)中,让编译器知道该段或组确实存在。
四、注意事项
1、.386代码模式中,条件转移指令(如jl、jb等)和far jmp与.286及之前,所占用的字节数不一致,即在386代码模式中,条件转移指令不再限制为short jmp(注意.386与.model的顺序)。
2、如果不是向前引用,jmp short和jmp near不用区分,编译器会根据实际情况判断,因此只需要jmp target即可,跨段跳转才需要明确指定jmp far ptr target。
3、proc如果不是向前引用,只需call myproc即可,不区分near和far,编译器会自动判断。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)