?? nasm.c
字號:
switch (i) {
case 1: /* [SEGMENT n] */
seg = ofmt->section (value, pass2, &sb);
if (seg == NO_SEG) {
report_error (pass1==1 ? ERR_NONFATAL : ERR_PANIC,
"segment name `%s' not recognised",
value);
} else {
in_abs_seg = FALSE;
location.segment = seg;
}
break;
case 2: /* [EXTERN label:special] */
if (*value == '$') value++; /* skip initial $ if present */
if (pass0 == 2) {
q = value;
while (*q && *q != ':')
q++;
if (*q == ':') {
*q++ = '\0';
ofmt->symdef(value, 0L, 0L, 3, q);
}
} else if (pass == 1) { /* pass == 1 */
q = value;
validid = TRUE;
if (!isidstart(*q))
validid = FALSE;
while (*q && *q != ':') {
if (!isidchar(*q))
validid = FALSE;
q++;
}
if (!validid) {
report_error (ERR_NONFATAL,
"identifier expected after EXTERN");
break;
}
if (*q == ':') {
*q++ = '\0';
special = q;
} else
special = NULL;
if (!is_extern(value)) { /* allow re-EXTERN to be ignored */
int temp = pass0;
pass0 = 1; /* fake pass 1 in labels.c */
declare_as_global (value, special, report_error);
define_label (value, seg_alloc(), 0L, NULL, FALSE, TRUE,
ofmt, report_error);
pass0 = temp;
}
} /* else pass0 == 1 */
break;
case 3: /* [BITS bits] */
sb = get_bits(value);
break;
case 4: /* [GLOBAL symbol:special] */
if (*value == '$') value++; /* skip initial $ if present */
if (pass0 == 2) { /* pass 2 */
q = value;
while (*q && *q != ':')
q++;
if (*q == ':') {
*q++ = '\0';
ofmt->symdef(value, 0L, 0L, 3, q);
}
} else if (pass2 == 1) { /* pass == 1 */
q = value;
validid = TRUE;
if (!isidstart(*q))
validid = FALSE;
while (*q && *q != ':') {
if (!isidchar(*q))
validid = FALSE;
q++;
}
if (!validid) {
report_error (ERR_NONFATAL,
"identifier expected after GLOBAL");
break;
}
if (*q == ':') {
*q++ = '\0';
special = q;
} else
special = NULL;
declare_as_global (value, special, report_error);
} /* pass == 1 */
break;
case 5: /* [COMMON symbol size:special] */
if (*value == '$') value++; /* skip initial $ if present */
if (pass0 == 1) {
p = value;
validid = TRUE;
if (!isidstart(*p))
validid = FALSE;
while (*p && !isspace(*p)) {
if (!isidchar(*p))
validid = FALSE;
p++;
}
if (!validid) {
report_error (ERR_NONFATAL,
"identifier expected after COMMON");
break;
}
if (*p) {
long size;
while (*p && isspace(*p))
*p++ = '\0';
q = p;
while (*q && *q != ':')
q++;
if (*q == ':') {
*q++ = '\0';
special = q;
} else
special = NULL;
size = readnum (p, &rn_error);
if (rn_error)
report_error (ERR_NONFATAL, "invalid size specified"
" in COMMON declaration");
else
define_common (value, seg_alloc(), size,
special, ofmt, report_error);
} else
report_error (ERR_NONFATAL, "no size specified in"
" COMMON declaration");
} else if (pass0 == 2) { /* pass == 2 */
q = value;
while (*q && *q != ':') {
if (isspace(*q))
*q = '\0';
q++;
}
if (*q == ':') {
*q++ = '\0';
ofmt->symdef(value, 0L, 0L, 3, q);
}
}
break;
case 6: /* [ABSOLUTE address] */
stdscan_reset();
stdscan_bufptr = value;
tokval.t_type = TOKEN_INVALID;
e = evaluate(stdscan, NULL, &tokval, NULL, pass2, report_error,
NULL);
if (e) {
if (!is_reloc(e))
report_error (pass0==1 ? ERR_NONFATAL : ERR_PANIC,
"cannot use non-relocatable expression as "
"ABSOLUTE address");
else {
abs_seg = reloc_seg(e);
abs_offset = reloc_value(e);
}
} else
if (pass==1) abs_offset = 0x100;/* don't go near zero in case of / */
else report_error (ERR_PANIC, "invalid ABSOLUTE address "
"in pass two");
in_abs_seg = TRUE;
location.segment = NO_SEG;
break;
case 7: /* DEBUG */
p = value;
q = debugid;
validid = TRUE;
if (!isidstart(*p))
validid = FALSE;
while (*p && !isspace(*p)) {
if (!isidchar(*p))
validid = FALSE;
*q++ = *p++;
}
*q++ = 0;
if (!validid) {
report_error (pass==1 ? ERR_NONFATAL : ERR_PANIC,
"identifier expected after DEBUG");
break;
}
while (*p && isspace(*p)) p++;
if (pass==pass_max) ofmt->current_dfmt->debug_directive (debugid, p);
break;
case 8: /* [WARNING {+|-}warn-name] */
if (pass1 == 1) {
while (*value && isspace(*value))
value++;
if (*value == '+' || *value == '-') {
validid = (*value == '-') ? TRUE : FALSE;
value++;
} else
validid = FALSE;
for (i=1; i<=ERR_WARN_MAX; i++)
if (!nasm_stricmp(value, suppressed_names[i]))
break;
if (i <= ERR_WARN_MAX)
suppressed[i] = validid;
else
report_error (ERR_NONFATAL, "invalid warning id in WARNING directive");
}
break;
case 9: /* cpu */
cpu = get_cpu (value);
break;
case 10: /* fbk 9/2/00 */ /* [LIST {+|-}] */
while (*value && isspace(*value))
value++;
if (*value == '+') {
user_nolist = 0;
}
else {
if (*value == '-') {
user_nolist = 1;
}
else {
report_error (ERR_NONFATAL, "invalid parameter to \"list\" directive");
}
}
break;
default:
if (!ofmt->directive (directive, value, pass2))
report_error (pass1==1 ? ERR_NONFATAL : ERR_PANIC,
"unrecognised directive [%s]",
directive);
}
}
else /* it isn't a directive */
{
parse_line (pass1, line, &output_ins,
report_error, evaluate,
def_label);
if (!(optimizing>0) && pass == 2) {
if (forwref != NULL && globallineno == forwref->lineno) {
output_ins.forw_ref = TRUE;
do {
output_ins.oprs[forwref->operand].opflags |= OPFLAG_FORWARD;
forwref = saa_rstruct (forwrefs);
} while (forwref != NULL && forwref->lineno == globallineno);
} else
output_ins.forw_ref = FALSE;
}
if (!(optimizing>0) && output_ins.forw_ref)
{
if (pass == 1) {
for(i = 0; i < output_ins.operands; i++)
{
if (output_ins.oprs[i].opflags & OPFLAG_FORWARD)
{
struct forwrefinfo *fwinf =
(struct forwrefinfo *)saa_wstruct(forwrefs);
fwinf->lineno = globallineno;
fwinf->operand = i;
}
}
} else { /* pass == 2 */
/*
* Hack to prevent phase error in the code
* rol ax,x
* x equ 1
*
* If the second operand is a forward reference,
* the UNITY property of the number 1 in that
* operand is cancelled. Otherwise the above
* sequence will cause a phase error.
*
* This hack means that the above code will
* generate 286+ code.
*
* The forward reference will mean that the
* operand will not have the UNITY property on
* the first pass, so the pass behaviours will
* be consistent.
*/
if (output_ins.operands >= 2 &&
(output_ins.oprs[1].opflags & OPFLAG_FORWARD))
{
output_ins.oprs[1].type &= ~(ONENESS|BYTENESS);
}
} /* pass == 2 */
} /* forw_ref */
if (output_ins.opcode == I_EQU) {
if (pass1 == 1)
{
/*
* Special `..' EQUs get processed in pass two,
* except `..@' macro-processor EQUs which are done
* in the normal place.
*/
if (!output_ins.label)
report_error (ERR_NONFATAL,
"EQU not preceded by label");
else if (output_ins.label[0] != '.' ||
output_ins.label[1] != '.' ||
output_ins.label[2] == '@')
{
if (output_ins.operands == 1 &&
(output_ins.oprs[0].type & IMMEDIATE) &&
output_ins.oprs[0].wrt == NO_SEG)
{
int isext = output_ins.oprs[0].opflags & OPFLAG_EXTERN;
def_label (output_ins.label,
output_ins.oprs[0].segment,
output_ins.oprs[0].offset,
NULL, FALSE, isext, ofmt, report_error);
}
else if (output_ins.operands == 2 &&
(output_ins.oprs[0].type & IMMEDIATE) &&
(output_ins.oprs[0].type & COLON) &&
output_ins.oprs[0].segment == NO_SEG &&
output_ins.oprs[0].wrt == NO_SEG &&
(output_ins.oprs[1].type & IMMEDIATE) &&
output_ins.oprs[1].segment == NO_SEG &&
output_ins.oprs[1].wrt == NO_SEG)
{
def_label (output_ins.label,
output_ins.oprs[0].offset | SEG_ABS,
output_ins.oprs[1].offset,
NULL, FALSE, FALSE, ofmt, report_error);
}
else
report_error(ERR_NONFATAL, "bad syntax for EQU");
}
} else { /* pass == 2 */
/*
* Special `..' EQUs get processed here, except
* `..@' macro processor EQUs which are done above.
*/
if (output_ins.label[0] == '.' &&
output_ins.label[1] == '.' &&
output_ins.label[2] != '@')
{
if (output_ins.operands == 1 &&
(output_ins.oprs[0].type & IMMEDIATE)) {
define_label (output_ins.label,
output_ins.oprs[0].segment,
output_ins.oprs[0].offset,
NULL, FALSE, FALSE, ofmt, report_error);
}
else if (output_ins.operands == 2 &&
(output_ins.oprs[0].type & IMMEDIATE) &&
(output_ins.oprs[0].type & COLON) &&
output_ins.oprs[0].segment == NO_SEG &&
(output_ins.oprs[1].type & IMMEDIATE) &&
output_ins.oprs[1].segment == NO_SEG)
{
define_label (output_ins.label,
output_ins.oprs[0].offset | SEG_ABS,
output_ins.oprs[1].offset,
NULL, FALSE, FALSE, ofmt, report_error);
}
else
report_error(ERR_NONFATAL, "bad syntax for EQU");
}
} /* pass == 2 */
} else { /* instruction isn't an EQU */
if (pass1 == 1) {
long l = insn_size (location.segment, offs, sb, cpu,
&output_ins, report_error);
/* if (using_debug_info) && output_ins.opcode != -1)*/
if (using_debug_info) /* fbk 03/25/01 */
{
/* this is done here so we can do debug type info */
long typeinfo = TYS_ELEMENTS(output_ins.operands);
switch (output_ins.opcode) {
case I_RESB:
typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_BYTE;
break;
case I_RESW:
typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_WORD;
break;
case I_RESD:
typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_DWORD;
break;
case I_RESQ:
typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_QWORD;
break;
case I_REST:
typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_TBYTE;
break;
case I_DB:
typeinfo |= TY_BYTE;
break;
case I_DW:
typeinfo |= TY_WORD;
break;
case I_DD:
if (output_ins.eops_float)
typeinfo |= TY_FLOAT;
else
typeinfo |= TY_DWORD;
break;
case I_DQ:
typeinfo |= TY_QWORD;
break;
case I_DT:
typeinfo |= TY_TBYTE;
break;
default:
typeinfo = TY_LABEL;
}
ofmt->current_dfmt->debug_typevalue(typeinfo);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -