NASM手册阅读笔记(5)

上下文堆

解释

    就是一个在编译期间由编译器维护的堆栈

之前说了预处理器的作用是在编译阶段执行一些代码,以简化或者增强汇编代码的能力,就像汇编代码本身执行的过程中需要一个堆栈存储一些信息一样,预处理器的指令在运行过程中也是需要存储一些信息的,那么这个上下文栈就是存储信息的地方

但是它比堆栈更强大,堆栈是只能存储一个值,而上下文栈是可以在每层存储很多信息

类比的话就是堆栈的每一层都是一个有名字的容器,你可以在每一层的容器里存储各种各样的东西。

%push  / %pop  

格式

%push 随便起个名字
%pop
 

       说明

      %push foobar  就是添加一个名字到foobar的容器到栈顶,以后可以使用可以使用宏 %ifctx foobar来判断
      %pop 就是删除并销毁栈顶容器
    

  %$ / %$$ / %$$ /.....

格式

      %$LABEL
      %$$LABEL
      %$$$LABEL

说明

这一些列标识符就相当于取堆栈中的容器的意思,%$ 就是去栈顶元素  %$$ 取相对于栈顶的第二个元素,以此类推
所以也有点 vector 的下标的意思
可以用它来定义子标签(本地标签)子宏(本地宏)
%$LABEL1:    将当前位置在栈顶容器里定义一个子标签叫 LABLE1
%$$LABEL2:     将当前位置在相对于栈顶的第二个容器里定义一个子标签叫 LABLE2
%$$$LABEL3:     将当前位置在相对于栈顶的第三个容器里定义一个子标签叫 LABLE3
 
                %define %$localmacro    将当前位置在栈顶容器里定义一个宏叫 localmacro  
 
            之后只要保持栈顶相同,那么就可以在任意地方直接使用%$LABEL 进行转跳
比如 
 
%macro repeat 0                   
  %push   repeat            ; 增加一个容器,命名为repeat
  %$begin:                      ; 将当前位置在新增加的容器里定义一个子标签,我们可以认为实际就是定义了一个repeat.begin标签
%endmacro               
            
%macro until 0                      
   jmp    %$begin            ;  转跳到 %$begin ( repeat.begin )
  %pop                  ; 这里栈顶发生变化了,所以不能在使用%&begin了,因为repeat容器没了
%endmacro 
        

%repl 

  对栈顶容器进行改名,他只改变名字并没有实际操作容器内容,所以之前在容器中的内容还是安全的
  预支相比的
  %pop
  %push XXX
  指令也能起到改名的作用,但是在调用%pop的时候容器中的内容就被销毁了,所以这是不安全的。当然也可以把它当成重置命令来用。
 
原文地址:https://www.cnblogs.com/alwaysking/p/12287443.html