NASM源代码分析—入口函数main()(1)

来源:互联网 发布:淘宝天机平台论坛 编辑:程序博客网 时间:2024/06/05 23:03
 
NASM源代码分析入口函数main()(1)
       之前我们简单讨论了与预处理有关的几个数据结构,下面我们根据NASM的入口开始讲解NASM的预处理机制。
 
入口函数nasm.c/main():
int main(int argc, char **argv)
{
    want_usage = terminate_after_phase = FALSE;
    nasm_set_malloc_error (report_error);                    (1)
    offsets = raa_init();                                    (2) // 初始化RAA结构
forwrefs = saa_init ((long)sizeof(struct forwrefinfo)); (3) // 初始化SAA结构
     preproc = &nasmpp;                                      (4)
    operating_mode = op_normal;                              (5)
    error_file = stderr;                                     (6)
    seg_init();                                              (7)
register_output_formats();                               (8)
 
(1): 设置申请内存空间(malloc)出错时的错误报告函数,初始化为report_error
(2,3):为RAASAA结构申请内存空间。NASM在运行时会动态分配两块内存。一块用来进行随机内存存取(RAA),以树状结构表示,每个叶结点中存储实际的数据;另一块用来进行顺序内存存取(SAA),以链状结构表示。这样程序在需要许多小的内存块时就不必每次去分配,只在已分配的内存块被用完时再分配。即提高了效率,也易于管理。
     (
注:SAA:dynamic sequential-access array.
        RAA:dynamic random access array.)
(4):设置有关预处理的标准处理函数,nasmpp代表的预处理的3个函数:
      pp_reset:设置错误处理函数(report_error)、列表处理函数(nasmlist)evaluate函数,初始化上下文栈cstk和文件包含栈istk,初始化RAASAA(清零)。
      pp_getline:从源代码文件中读取一行代码,并处理之。
      pp_cleanup:扫尾工作。
以上函数的具体功能,我们在以后再讨论。
(5)设置nasm的执行模式,共分为3种模式:
      enum op_type
{
           op_normal,             /* Preprocess and assemble */
          op_preprocess,        /* Preprocess only */
  op_depend              /* Generate dependencies */
};
      分别是op_normal,这是默认模式,就是将源代码预处理并汇编成二进制代码,我们讨论玩预处理模式后,降探讨这个模式;op_preprocess,只进行预处理,这也是我们现在探讨的模式,通过在执行NASM时添加参数 –e 即可;op_depend产生文件依赖关系,这个模式很简单,我们不涉及,执行NASM时添加参数–M
      (6)设置出错信息输出,默认是stderr,也就是将出错信息输出到显示器上,也可以通过添加参数-E来指定将出错信息输出到某个特定的文件中。
      (7)初始化segment, 只执行一个代码:next_seg = 0;
      (8)注册输出格式信息,NASM支持有种文件输出格式,如Linux平台的elfa.out格式和windows平台的objwin32格式等,这里只是初始化!!!
 
接楼上代码:
      parse_cmdline(argc, argv);                         (1)
    if (terminate_after_phase)                          (2)
    {    if (want_usage)
              usage();
         return 1;
    }
    if (ofmt->stdmac)                                   (3)
         pp_extra_stdmac (ofmt->stdmac);
    parser_global_info (ofmt, &location);               (4)
eval_global_info (ofmt, lookup_label, &location);   (5)
 
(1) 参数分析,下篇将具体讲解这个函数。
(2) 是否显示NASM的使用信息,usage()即为显示使用信息,就是输入nasm –h后产生的信息。
(3) 变量ofmt表示nasm输出文件的格式,通过nasm的参数-o指定,由函数parse_cmdline()处理。语句(3)处理该输出格式的标准宏,标准宏的定义在文件Marcos.c中,这就是为什么我们没有定义宏__NASM_MAJOR__,却仍可以使用这个宏的原因,因为系统已经定义好了。
(4,5)初始化一些全局变量,后面再分析。
 
 
原创粉丝点击