Chinaunix首页 | 论坛 | 博客
  • 博客访问: 11383
  • 博文数量: 4
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-23 02:30
文章分类
文章存档

2016年(4)

我的朋友
最近访客

分类: LINUX

2016-08-11 12:03:09

原文地址:伪指令的识别 作者:qtdszws

main->perform_an_assembly_pass->read_a_source_file

1.将输入转换成小写

{
        {
          /* Expect pseudo-op or machine instruction.  */
          pop = NULL;

#ifndef TC_CASE_SENSITIVE//TC_CASE_SENSITIVE未定义
          {
            char *s2 = s;//当前处理位置

            strncpy (original_case_string, s2, sizeof (original_case_string));//保存原始字符串
            original_case_string[sizeof (original_case_string) - 1] = 0;

            while (*s2)
              {
            *s2 = TOLOWER (*s2);//全部转换成小写
            s2++;
              }
          }
#endif
}

original_case_string的定义是

#ifndef TC_CASE_SENSITIVE
char original_case_string[128];
#endif

不过这个original_case_string只有arm平台用到了,所以可以忽略

2.在hash表中查找伪指令

{
          if (NO_PSEUDO_DOT || flag_m68k_mri)//386平台为0,忽略
            {
              /* The MRI assembler uses pseudo-ops without
             a period.  */
              pop = (pseudo_typeS *) hash_find (po_hash, s);
              if (pop != NULL && pop->poc_handler == NULL)
            pop = NULL;
            }

          if (pop != NULL//POP==NULL
              || (!flag_m68k_mri && *s == '.'))
//上面的判断等价于if(*s=='.')
            {
              /* PSEUDO - OP.

             WARNING: c has next char, which may be end-of-line.
             We lookup the pseudo-op table with s+1 because we
             already know that the pseudo-op begins with a '.'.  */

              if (pop == NULL)//肯定为NULL,可忽略
            pop = (pseudo_typeS *) hash_find (po_hash, s + 1);//在po_hash中查找对应的伪指令
              if (pop && !pop->poc_handler)//找到,但是没有处理句柄,无效
            pop = NULL;

              /* In MRI mode, we may need to insert an
             automatic alignment directive.  What a hack
             this is.  */
              if (mri_pending_align// mri_pending_align==0,忽略本if
              && (pop == NULL
                  || !((pop->poc_handler == cons
                    && pop->poc_val == 1)
                   || (pop->poc_handler == s_space
                       && pop->poc_val == 1)
#ifdef tc_conditional_pseudoop
                   || tc_conditional_pseudoop (pop)
#endif
                   || pop->poc_handler == s_if
                   || pop->poc_handler == s_ifdef
                   || pop->poc_handler == s_ifc
                   || pop->poc_handler == s_ifeqs
                   || pop->poc_handler == s_else
                   || pop->poc_handler == s_endif
                   || pop->poc_handler == s_globl
                   || pop->poc_handler == s_ignore)))
            {
              do_align (1, (char *) NULL, 0, 0);
              mri_pending_align = 0;

              if (line_label != NULL)
                {
                  symbol_set_frag (line_label, frag_now);
                  S_SET_VALUE (line_label, frag_now_fix ());
                }
            }
}

3.如果没有找到该伪指令,尝试是否是宏并处理
{

              /* Print the error msg now, while we still can.  */
              if (pop == NULL)//没有找到对应的"伪指令",可能是宏
            {
              char *end = input_line_pointer;//保存input_line_pointer

//还原c
//例如宏调要 .a 1,2  
//c为a后面的字符,即空格
//前面调用  c = get_symbol_end ();    /* name's delimiter. c是符号后面的第一个字符,分隔符 */
//时保存的并将0写入该处,现在还原
              *input_line_pointer = c;

              s_ignore (0);//忽略本行,将input_line_pointer推到下一行
              c = *--input_line_pointer;//input_line_pointer回到上一行行尾,c=='\n'
              *input_line_pointer = '\0';//截断
              if (! macro_defined || ! try_macro (c, s))//当定义了宏时,macro_defined为1,则尝试是否宏调用
                {
                  *end = '\0';//end指向.a后,截断
                  as_bad (_("unknown pseudo-op: `%s'"), s);//出错
                  *input_line_pointer++ = c;//还原c即空格
                }
              continue;
            }
}

4.找到了该伪指令,调用处理函数
{
//到这里找到了该伪指令,例如.align 2

              /* Put it back for error messages etc.  */
              *input_line_pointer = c;//还原c
              /* The following skip of whitespace is compulsory.
             A well shaped space is sometimes all that separates
             keyword from operands.  */
              if (c == ' ' || c == '\t')
            input_line_pointer++;//跳过空格

              /* Input_line is restored.
             Input_line_pointer->1st non-blank char
             after pseudo-operation.  */
              (*pop->poc_handler) (pop->poc_val);//调用伪指令的处理函数,使用poc_val为参数

              /* If that was .end, just get out now.  */
              if (pop->poc_handler == s_end)//如果是.end伪指令,结束处理
            goto quit;
            }

}

阅读(1103) | 评论(0) | 转发(0) |
0

上一篇:伪指令初始化

下一篇:align(1)

给主人留下些什么吧!~~