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,编译器会自动判断。

posted @ 2024-05-18 15:42  美洲象  阅读(21)  评论(0编辑  收藏  举报