鱼C论坛

 找回密码
 立即注册

小甲鱼的徒弟

https://fishc.com.cn/?41

宏汇编语言控制台程序的“宏” 解析

已有 303 次阅读2010-12-10 10:11 |个人分类:汇编语言

虽然我们不提倡用宏,宏本质上只不过是一种替换而已。
但宏汇编语言控制台程序中却大量使用了宏。经研究后,发现某些宏用起来确实方便。
这里推荐4个,chr$, str$,print,input
当然,象那些简单的宏例如exit 宏,就随你意愿可用可不用了。

下面是控制台程序中常用的宏:
1. 控制台程序 print 宏的完全解析

例子程序可以参考宏汇编的tutorial\console 下的程序,我们重点分析一句代码:
print chr$("Hey, this actually works.",13,10)
先看chr$ 宏
      chr$ MACRO any_text:VARARG
        LOCAL txtname
        .data
          txtname db any_text,0
        .code
        EXITM <OFFSET txtname>
      ENDM
chr$ 是带一个参数的宏。
1. 在数据区中定义一个标号txtname,这个标号是局部的,意思是说,仅在该宏中有意义。
  然后把后续的参数定义到数据区中,尾巴补0.
2. 宏结束,返回一个标号地址。

再看print 宏
    print MACRO arg1:REQ,varname:VARARG      ;; display zero terminated string
        invoke StdOut,reparg(arg1)
      IFNB <varname>
        invoke StdOut,chr$(varname)
      ENDIF
    ENDM

1. print 宏似乎带2个参数的宏?一个arg1, 一个varname, varname 可以为空。当为空时,只替代第一句。
invoke  StdOut, reparg(arg1)       

再看reparg (arg1) 宏
 ; -----------------------------------------------------------
 ; This macro replaces quoted text with a DATA section OFFSET
 ; and returns it in ADDR "name" format. It is used by other
 ; macros that handle optional quoted text as a parameter.
 ; -----------------------------------------------------------
   reparg MACRO arg
     LOCAL nustr
       quot SUBSTR <arg>,1,1
     IFIDN quot,<">            ;; if 1st char = "
       .data
         nustr db arg,0        ;; write arg to .DATA section
       .code
       EXITM <ADDR nustr>      ;; append name to ADDR operator
     ELSE
       EXITM <arg>             ;; else return arg
     ENDIF
   ENDM  
   
1. 判断参数第一个字符是否为", 如是, 定义为数据区,末尾补0,返回地址。否则,直接退出。返回原arg.
  可见,args 经replace 宏替代后,可以不用chr$ 宏
; ---------------------------------------------------------------------------
分析完后,可以做个新实验。
改原句为如下,应也可工作   
print "Hey, this actually works.",13,10

虽然打印结果没有变化,但实际宏的控制过程却是改变了的。   
实际宏的工作过程是,将print 后所跟参数看成两个参数, "Hey, this actually works." 为第一参数,replace 参数,
第二部分13,10 ... 为可变参数,print 的第二参数, 用chr$ 宏修饰之。所以编译的结果形成两条语句。
       invoke StdOut,reparg(arg1)          .data
                    ??0019 db "Hey, this actually works.",0        
                  .code
                  invoke StdOut,ADDR ??0019

       invoke StdOut,chr$(varname)       .data
                    ??001A db 13,10,0
                  .code
                  invoke StdOut,OFFSET ??001A  
  也一样能满足要求。
如此看来,用chr$ 修饰字符串,有更高的效率。
print chr$("Hey, this actually works.",13,10)  .data
                    ??0019 db "Hey, this actually works.",13,10,0
            invoke StdOut,OFFSET ??0019
; ---------------------------------------------------------------------------
说了一大堆,到底得出点什么结论呢?两点最重要
1. chr$ 是个宏,用来定义0字终结字符串。
2. print 是个宏,用来执行StdOut 函数。


另外,关于exit 宏:如下定义
 ; --------------------------------------------------------
 ; exit macro with an optional return value for ExitProcess
 ; --------------------------------------------------------
   exit MACRO optional_return_value
     IFNDEF optional_return_value
       invoke ExitProcess, 0
     ELSE
       invoke ExitProcess,optional_return_value
     ENDIF
   ENDM
也就是说,根据exit 宏是否带参数,将被翻译成不同的ExitProcess 函数。

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-6-8 21:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

返回顶部