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;
}
}
阅读(1894) | 评论(0) | 转发(1) |