1 /* assemble.c code generation for the Netwide Assembler
3 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
4 * Julian Hall. All rights reserved. The software is
5 * redistributable under the licence given in the file "Licence"
6 * distributed in the NASM archive.
8 * the actual codes (C syntax, i.e. octal):
9 * \0 - terminates the code. (Unless it's a literal of course.)
10 * \1, \2, \3 - that many literal bytes follow in the code stream
11 * \4, \6 - the POP/PUSH (respectively) codes for CS, DS, ES, SS
12 * (POP is never used for CS) depending on operand 0
13 * \5, \7 - the second byte of POP/PUSH codes for FS, GS, depending
15 * \10, \11, \12 - a literal byte follows in the code stream, to be added
16 * to the register value of operand 0, 1 or 2
17 * \17 - encodes the literal byte 0. (Some compilers don't take
18 * kindly to a zero byte in the _middle_ of a compile time
19 * string constant, so I had to put this hack in.)
20 * \14, \15, \16 - a signed byte immediate operand, from operand 0, 1 or 2
21 * \20, \21, \22 - a byte immediate operand, from operand 0, 1 or 2
22 * \24, \25, \26 - an unsigned byte immediate operand, from operand 0, 1 or 2
23 * \30, \31, \32 - a word immediate operand, from operand 0, 1 or 2
24 * \34, \35, \36 - select between \3[012] and \4[012] depending on 16/32 bit
25 * assembly mode or the address-size override on the operand
26 * \37 - a word constant, from the _segment_ part of operand 0
27 * \40, \41, \42 - a long immediate operand, from operand 0, 1 or 2
28 * \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2
29 * \60, \61, \62 - a word relative operand, from operand 0, 1 or 2
30 * \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit
31 * assembly mode or the address-size override on the operand
32 * \70, \71, \72 - a long relative operand, from operand 0, 1 or 2
33 * \1ab - a ModRM, calculated on EA in operand a, with the spare
34 * field the register value of operand b.
35 * \130,\131,\132 - an immediate word or signed byte for operand 0, 1, or 2
36 * \133,\134,\135 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
37 * is a signed byte rather than a word.
38 * \140,\141,\142 - an immediate dword or signed byte for operand 0, 1, or 2
39 * \143,\144,\145 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
40 * is a signed byte rather than a dword.
41 * \2ab - a ModRM, calculated on EA in operand a, with the spare
42 * field equal to digit b.
43 * \30x - might be an 0x67 byte, depending on the address size of
44 * the memory reference in operand x.
45 * \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
46 * \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
47 * \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
48 * \320 - indicates fixed 16-bit operand size, i.e. optional 0x66.
49 * \321 - indicates fixed 32-bit operand size, i.e. optional 0x66.
50 * \322 - indicates that this instruction is only valid when the
51 * operand size is the default (instruction to disassembler,
52 * generates no code in the assembler)
53 * \330 - a literal byte follows in the code stream, to be added
54 * to the condition code value of the instruction.
55 * \331 - instruction not valid with REP prefix. Hint for
56 * disassembler only; for SSE instructions.
57 * \332 - disassemble a rep (0xF3 byte) prefix as repe not rep.
58 * \333 - REP prefix (0xF3 byte); for SSE instructions. Not encoded
59 * as a literal byte in order to aid the disassembler.
60 * \340 - reserve <operand 0> bytes of uninitialised storage.
61 * Operand 0 had better be a segmentless constant.
62 * \370,\371,\372 - match only if operand 0 meets byte jump criteria.
63 * 370 is used for Jcc, 371 is used for JMP.
64 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32;
65 * used for conditional jump over longer jump
76 extern struct itemplate
*nasm_instructions
[];
79 int sib_present
; /* is a SIB byte necessary? */
80 int bytes
; /* # of bytes of offset needed */
81 int size
; /* lazy - this is sib+bytes+1 */
82 unsigned char modrm
, sib
; /* the bytes themselves */
85 static unsigned long cpu
; /* cpu level received from nasm.c */
87 static struct ofmt
*outfmt
;
90 static long calcsize (long, long, int, insn
*, char *);
91 static void gencode (long, long, int, insn
*, char *, long);
92 static int regval (operand
*o
);
93 static int matches (struct itemplate
*, insn
*);
94 static ea
* process_ea (operand
*, ea
*, int, int, int);
95 static int chsize (operand
*, int);
98 * This routine wrappers the real output format's output routine,
99 * in order to pass a copy of the data off to the listing file
100 * generator at the same time.
102 static void out (long offset
, long segto
, void *data
, unsigned long type
,
103 long segment
, long wrt
)
106 static char *lnfname
;
108 if ((type
& OUT_TYPMASK
) == OUT_ADDRESS
) {
109 if (segment
!= NO_SEG
|| wrt
!= NO_SEG
) {
111 * This address is relocated. We must write it as
112 * OUT_ADDRESS, so there's no work to be done here.
114 list
->output (offset
, data
, type
);
117 unsigned char p
[4], *q
= p
;
119 * This is a non-relocated address, and we're going to
120 * convert it into RAWDATA format.
122 if ((type
& OUT_SIZMASK
) == 4) {
123 WRITELONG (q
, * (long *) data
);
124 list
->output (offset
, p
, OUT_RAWDATA
+4);
127 WRITESHORT (q
, * (long *) data
);
128 list
->output (offset
, p
, OUT_RAWDATA
+2);
132 else if ((type
& OUT_TYPMASK
) == OUT_RAWDATA
) {
133 list
->output (offset
, data
, type
);
135 else if ((type
& OUT_TYPMASK
) == OUT_RESERVE
) {
136 list
->output (offset
, NULL
, type
);
138 else if ((type
& OUT_TYPMASK
) == OUT_REL2ADR
||
139 (type
& OUT_TYPMASK
) == OUT_REL4ADR
) {
140 list
->output (offset
, data
, type
);
143 if (src_get(&lineno
,&lnfname
))
144 outfmt
->current_dfmt
->linenum(lnfname
,lineno
,segto
);
146 outfmt
->output (segto
, data
, type
, segment
, wrt
);
149 static int jmp_match (long segment
, long offset
, int bits
,
150 insn
*ins
, char *code
)
152 unsigned char c
= code
[0];
155 if (c
!= 0370 && c
!= 0371) return 0;
156 if (ins
->oprs
[0].opflags
& OPFLAG_FORWARD
) {
157 if (optimizing
<0 && c
==0370) return 1;
158 else return (pass0
==0); /* match a forward reference */
160 isize
= calcsize (segment
, offset
, bits
, ins
, code
);
161 if (ins
->oprs
[0].segment
!= segment
) return 0;
162 isize
= ins
->oprs
[0].offset
- offset
- isize
; /* isize is now the delta */
163 if (isize
>= -128L && isize
<= 127L) return 1; /* it is byte size */
169 long assemble (long segment
, long offset
, int bits
, unsigned long cp
,
170 insn
*instruction
, struct ofmt
*output
, efunc error
,
173 struct itemplate
*temp
;
179 long wsize
= 0; /* size for DB etc. */
181 errfunc
= error
; /* to pass to other functions */
183 outfmt
= output
; /* likewise */
184 list
= listgen
; /* and again */
186 switch (instruction
->opcode
)
189 case I_DB
: wsize
= 1; break;
190 case I_DW
: wsize
= 2; break;
191 case I_DD
: wsize
= 4; break;
192 case I_DQ
: wsize
= 8; break;
193 case I_DT
: wsize
= 10; break;
198 long t
= instruction
->times
;
200 errfunc(ERR_PANIC
, "instruction->times < 0 (%ld) in assemble()",t
);
202 while (t
--) /* repeat TIMES times */
204 for (e
= instruction
->eops
; e
; e
= e
->next
)
206 if (e
->type
== EOT_DB_NUMBER
)
209 if (e
->segment
!= NO_SEG
)
210 errfunc (ERR_NONFATAL
,
211 "one-byte relocation attempted");
213 unsigned char out_byte
= e
->offset
;
214 out (offset
, segment
, &out_byte
, OUT_RAWDATA
+1,
218 else if (wsize
> 5) {
219 errfunc (ERR_NONFATAL
, "integer supplied to a D%c"
220 " instruction", wsize
==8 ? 'Q' : 'T');
223 out (offset
, segment
, &e
->offset
,
224 OUT_ADDRESS
+wsize
, e
->segment
,
228 else if (e
->type
== EOT_DB_STRING
)
232 out (offset
, segment
, e
->stringval
,
233 OUT_RAWDATA
+e
->stringlen
, NO_SEG
, NO_SEG
);
234 align
= e
->stringlen
% wsize
;
237 align
= wsize
- align
;
238 out (offset
, segment
, "\0\0\0\0\0\0\0\0",
239 OUT_RAWDATA
+align
, NO_SEG
, NO_SEG
);
241 offset
+= e
->stringlen
+ align
;
244 if (t
> 0 && t
== instruction
->times
-1)
247 * Dummy call to list->output to give the offset to the
250 list
->output (offset
, NULL
, OUT_RAWDATA
);
251 list
->uplevel (LIST_TIMES
);
254 if (instruction
->times
> 1)
255 list
->downlevel (LIST_TIMES
);
256 return offset
- start
;
259 if (instruction
->opcode
== I_INCBIN
)
261 static char fname
[FILENAME_MAX
];
265 len
= FILENAME_MAX
-1;
266 if (len
> instruction
->eops
->stringlen
)
267 len
= instruction
->eops
->stringlen
;
268 strncpy (fname
, instruction
->eops
->stringval
, len
);
271 if ( (fp
= fopen(fname
, "rb")) == NULL
)
272 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
273 else if (fseek(fp
, 0L, SEEK_END
) < 0)
274 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
278 static char buf
[2048];
279 long t
= instruction
->times
;
283 if (instruction
->eops
->next
) {
284 base
= instruction
->eops
->next
->offset
;
286 if (instruction
->eops
->next
->next
&&
287 len
> instruction
->eops
->next
->next
->offset
)
288 len
= instruction
->eops
->next
->next
->offset
;
291 * Dummy call to list->output to give the offset to the
294 list
->output (offset
, NULL
, OUT_RAWDATA
);
295 list
->uplevel(LIST_INCBIN
);
300 fseek (fp
, base
, SEEK_SET
);
303 long m
= fread (buf
, 1, (l
>sizeof(buf
)?sizeof(buf
):l
),
307 * This shouldn't happen unless the file
308 * actually changes while we are reading
311 error (ERR_NONFATAL
, "`incbin': unexpected EOF while"
312 " reading file `%s'", fname
);
313 t
=0; /* Try to exit cleanly */
316 out (offset
, segment
, buf
, OUT_RAWDATA
+m
,
321 list
->downlevel(LIST_INCBIN
);
322 if (instruction
->times
> 1) {
324 * Dummy call to list->output to give the offset to the
327 list
->output (offset
, NULL
, OUT_RAWDATA
);
328 list
->uplevel(LIST_TIMES
);
329 list
->downlevel(LIST_TIMES
);
332 return instruction
->times
* len
;
334 return 0; /* if we're here, there's an error */
338 temp
= nasm_instructions
[instruction
->opcode
];
339 while (temp
->opcode
!= -1) {
340 int m
= matches (temp
, instruction
);
342 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
344 if (m
== 100) /* matches! */
346 char *codes
= temp
->code
;
347 long insn_size
= calcsize(segment
, offset
, bits
,
349 itimes
= instruction
->times
;
350 if (insn_size
< 0) /* shouldn't be, on pass two */
351 error (ERR_PANIC
, "errors made it through from pass one");
352 else while (itimes
--) {
353 insn_end
= offset
+ insn_size
;
354 for (j
=0; j
<instruction
->nprefix
; j
++) {
356 switch (instruction
->prefixes
[j
]) {
359 case P_REPNE
: case P_REPNZ
:
361 case P_REPE
: case P_REPZ
: case P_REP
:
363 case R_CS
: c
= 0x2E; break;
364 case R_DS
: c
= 0x3E; break;
365 case R_ES
: c
= 0x26; break;
366 case R_FS
: c
= 0x64; break;
367 case R_GS
: c
= 0x65; break;
368 case R_SS
: c
= 0x36; break;
387 "invalid instruction prefix");
390 out (offset
, segment
, &c
, OUT_RAWDATA
+1,
395 gencode (segment
, offset
, bits
, instruction
, codes
, insn_end
);
397 if (itimes
> 0 && itimes
== instruction
->times
-1) {
399 * Dummy call to list->output to give the offset to the
402 list
->output (offset
, NULL
, OUT_RAWDATA
);
403 list
->uplevel (LIST_TIMES
);
406 if (instruction
->times
> 1)
407 list
->downlevel (LIST_TIMES
);
408 return offset
- start
;
409 } else if (m
> 0 && m
> size_prob
) {
415 if (temp
->opcode
== -1) { /* didn't match any instruction */
416 if (size_prob
== 1) /* would have matched, but for size */
417 error (ERR_NONFATAL
, "operation size not specified");
418 else if (size_prob
== 2)
419 error (ERR_NONFATAL
, "mismatch in operand sizes");
420 else if (size_prob
== 3)
421 error (ERR_NONFATAL
, "no instruction for this cpu level");
424 "invalid combination of opcode and operands");
429 long insn_size (long segment
, long offset
, int bits
, unsigned long cp
,
430 insn
*instruction
, efunc error
)
432 struct itemplate
*temp
;
434 errfunc
= error
; /* to pass to other functions */
437 if (instruction
->opcode
== -1)
440 if (instruction
->opcode
== I_DB
||
441 instruction
->opcode
== I_DW
||
442 instruction
->opcode
== I_DD
||
443 instruction
->opcode
== I_DQ
||
444 instruction
->opcode
== I_DT
)
447 long isize
, osize
, wsize
= 0; /* placate gcc */
450 switch (instruction
->opcode
)
452 case I_DB
: wsize
= 1; break;
453 case I_DW
: wsize
= 2; break;
454 case I_DD
: wsize
= 4; break;
455 case I_DQ
: wsize
= 8; break;
456 case I_DT
: wsize
= 10; break;
459 for (e
= instruction
->eops
; e
; e
= e
->next
)
464 if (e
->type
== EOT_DB_NUMBER
)
466 else if (e
->type
== EOT_DB_STRING
)
467 osize
= e
->stringlen
;
469 align
= (-osize
) % wsize
;
472 isize
+= osize
+ align
;
474 return isize
* instruction
->times
;
477 if (instruction
->opcode
== I_INCBIN
)
479 char fname
[FILENAME_MAX
];
483 len
= FILENAME_MAX
-1;
484 if (len
> instruction
->eops
->stringlen
)
485 len
= instruction
->eops
->stringlen
;
486 strncpy (fname
, instruction
->eops
->stringval
, len
);
488 if ( (fp
= fopen(fname
, "rb")) == NULL
)
489 error (ERR_NONFATAL
, "`incbin': unable to open file `%s'", fname
);
490 else if (fseek(fp
, 0L, SEEK_END
) < 0)
491 error (ERR_NONFATAL
, "`incbin': unable to seek on file `%s'",
497 if (instruction
->eops
->next
)
499 len
-= instruction
->eops
->next
->offset
;
500 if (instruction
->eops
->next
->next
&&
501 len
> instruction
->eops
->next
->next
->offset
)
503 len
= instruction
->eops
->next
->next
->offset
;
506 return instruction
->times
* len
;
508 return 0; /* if we're here, there's an error */
511 temp
= nasm_instructions
[instruction
->opcode
];
512 while (temp
->opcode
!= -1) {
513 int m
= matches(temp
, instruction
);
515 m
+= jmp_match(segment
, offset
, bits
, instruction
, temp
->code
);
518 /* we've matched an instruction. */
520 char * codes
= temp
->code
;
523 isize
= calcsize(segment
, offset
, bits
, instruction
, codes
);
526 for (j
= 0; j
< instruction
->nprefix
; j
++)
528 if ((instruction
->prefixes
[j
] != P_A16
&&
529 instruction
->prefixes
[j
] != P_O16
&& bits
==16) ||
530 (instruction
->prefixes
[j
] != P_A32
&&
531 instruction
->prefixes
[j
] != P_O32
&& bits
==32))
536 return isize
* instruction
->times
;
540 return -1; /* didn't match any instruction */
544 /* check that opn[op] is a signed byte of size 16 or 32,
545 and return the signed value*/
546 static int is_sbyte (insn
*ins
, int op
, int size
)
551 ret
= !(ins
->forw_ref
&& ins
->oprs
[op
].opflags
) && /* dead in the water on forward reference or External */
552 (optimizing
>0 || !(ins
->oprs
[op
].type
& (BITS16
|BITS32
))) &&
553 ins
->oprs
[op
].wrt
==NO_SEG
&& ins
->oprs
[op
].segment
==NO_SEG
;
555 v
= ins
->oprs
[op
].offset
;
556 if (size
==16) v
= (signed short)v
; /* sign extend if 16 bits */
558 return ret
&& v
>=-128L && v
<=127L;
561 static long calcsize (long segment
, long offset
, int bits
,
562 insn
*ins
, char *codes
)
567 (void) segment
; /* Don't warn that this parameter is unused */
568 (void) offset
; /* Don't warn that this parameter is unused */
570 while (*codes
) switch (c
= *codes
++) {
571 case 01: case 02: case 03:
572 codes
+= c
, length
+= c
; break;
573 case 04: case 05: case 06: case 07:
575 case 010: case 011: case 012:
576 codes
++, length
++; break;
579 case 014: case 015: case 016:
581 case 020: case 021: case 022:
583 case 024: case 025: case 026:
585 case 030: case 031: case 032:
587 case 034: case 035: case 036:
588 length
+= ((ins
->oprs
[c
-034].addr_size
?
589 ins
->oprs
[c
-034].addr_size
: bits
) == 16 ? 2 : 4); break;
592 case 040: case 041: case 042:
594 case 050: case 051: case 052:
596 case 060: case 061: case 062:
598 case 064: case 065: case 066:
599 length
+= ((ins
->oprs
[c
-064].addr_size
?
600 ins
->oprs
[c
-064].addr_size
: bits
) == 16 ? 2 : 4); break;
601 case 070: case 071: case 072:
603 case 0130: case 0131: case 0132:
604 length
+= is_sbyte(ins
, c
-0130, 16) ? 1 : 2; break;
605 case 0133: case 0134: case 0135:
606 codes
+=2; length
++; break;
607 case 0140: case 0141: case 0142:
608 length
+= is_sbyte(ins
, c
-0140, 32) ? 1 : 4; break;
609 case 0143: case 0144: case 0145:
610 codes
+=2; length
++; break;
611 case 0300: case 0301: case 0302:
612 length
+= chsize (&ins
->oprs
[c
-0300], bits
);
615 length
+= (bits
==32);
618 length
+= (bits
==16);
623 length
+= (bits
==32);
626 length
+= (bits
==16);
631 codes
++, length
++; break;
637 case 0340: case 0341: case 0342:
638 if (ins
->oprs
[0].segment
!= NO_SEG
)
639 errfunc (ERR_NONFATAL
, "attempt to reserve non-constant"
640 " quantity of BSS space");
642 length
+= ins
->oprs
[0].offset
<< (c
-0340);
644 case 0370: case 0371: case 0372:
648 default: /* can't do it by 'case' statements */
649 if (c
>=0100 && c
<=0277) { /* it's an EA */
651 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, 0,
653 errfunc (ERR_NONFATAL
, "invalid effective address");
656 length
+= ea_data
.size
;
658 errfunc (ERR_PANIC
, "internal instruction table corrupt"
659 ": instruction code 0x%02X given", c
);
664 static void gencode (long segment
, long offset
, int bits
,
665 insn
*ins
, char *codes
, long insn_end
)
667 static char condval
[] = { /* conditional opcodes */
668 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
669 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
670 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
673 unsigned char bytes
[4];
677 switch (c
= *codes
++)
679 case 01: case 02: case 03:
680 out (offset
, segment
, codes
, OUT_RAWDATA
+c
, NO_SEG
, NO_SEG
);
686 switch (ins
->oprs
[0].basereg
)
689 bytes
[0] = 0x0E + (c
== 0x04 ? 1 : 0); break;
691 bytes
[0] = 0x1E + (c
== 0x04 ? 1 : 0); break;
693 bytes
[0] = 0x06 + (c
== 0x04 ? 1 : 0); break;
695 bytes
[0] = 0x16 + (c
== 0x04 ? 1 : 0); break;
697 errfunc (ERR_PANIC
, "bizarre 8086 segment register received");
699 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
704 switch (ins
->oprs
[0].basereg
) {
705 case R_FS
: bytes
[0] = 0xA0 + (c
== 0x05 ? 1 : 0); break;
706 case R_GS
: bytes
[0] = 0xA8 + (c
== 0x05 ? 1 : 0); break;
708 errfunc (ERR_PANIC
, "bizarre 386 segment register received");
710 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
714 case 010: case 011: case 012:
715 bytes
[0] = *codes
++ + regval(&ins
->oprs
[c
-010]);
716 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
722 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
726 case 014: case 015: case 016:
727 if (ins
->oprs
[c
-014].offset
< -128
728 || ins
->oprs
[c
-014].offset
> 127)
730 errfunc (ERR_WARNING
, "signed byte value exceeds bounds");
733 if (ins
->oprs
[c
-014].segment
!= NO_SEG
)
735 data
= ins
->oprs
[c
-014].offset
;
736 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
737 ins
->oprs
[c
-014].segment
, ins
->oprs
[c
-014].wrt
);
740 bytes
[0] = ins
->oprs
[c
-014].offset
;
741 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
746 case 020: case 021: case 022:
747 if (ins
->oprs
[c
-020].offset
< -256
748 || ins
->oprs
[c
-020].offset
> 255)
750 errfunc (ERR_WARNING
, "byte value exceeds bounds");
752 if (ins
->oprs
[c
-020].segment
!= NO_SEG
) {
753 data
= ins
->oprs
[c
-020].offset
;
754 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
755 ins
->oprs
[c
-020].segment
, ins
->oprs
[c
-020].wrt
);
758 bytes
[0] = ins
->oprs
[c
-020].offset
;
759 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
764 case 024: case 025: case 026:
765 if (ins
->oprs
[c
-024].offset
< 0 || ins
->oprs
[c
-024].offset
> 255)
766 errfunc (ERR_WARNING
, "unsigned byte value exceeds bounds");
767 if (ins
->oprs
[c
-024].segment
!= NO_SEG
) {
768 data
= ins
->oprs
[c
-024].offset
;
769 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
770 ins
->oprs
[c
-024].segment
, ins
->oprs
[c
-024].wrt
);
773 bytes
[0] = ins
->oprs
[c
-024].offset
;
774 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
779 case 030: case 031: case 032:
780 if (ins
->oprs
[c
-030].segment
== NO_SEG
&&
781 ins
->oprs
[c
-030].wrt
== NO_SEG
&&
782 (ins
->oprs
[c
-030].offset
< -65536L ||
783 ins
->oprs
[c
-030].offset
> 65535L))
785 errfunc (ERR_WARNING
, "word value exceeds bounds");
787 data
= ins
->oprs
[c
-030].offset
;
788 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
789 ins
->oprs
[c
-030].segment
, ins
->oprs
[c
-030].wrt
);
793 case 034: case 035: case 036:
794 data
= ins
->oprs
[c
-034].offset
;
795 size
= ((ins
->oprs
[c
-034].addr_size
?
796 ins
->oprs
[c
-034].addr_size
: bits
) == 16 ? 2 : 4);
797 if (size
==2 && (data
< -65536L || data
> 65535L))
798 errfunc (ERR_WARNING
, "word value exceeds bounds");
799 out (offset
, segment
, &data
, OUT_ADDRESS
+size
,
800 ins
->oprs
[c
-034].segment
, ins
->oprs
[c
-034].wrt
);
805 if (ins
->oprs
[0].segment
== NO_SEG
)
806 errfunc (ERR_NONFATAL
, "value referenced by FAR is not"
809 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
810 outfmt
->segbase(1+ins
->oprs
[0].segment
),
815 case 040: case 041: case 042:
816 data
= ins
->oprs
[c
-040].offset
;
817 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
818 ins
->oprs
[c
-040].segment
, ins
->oprs
[c
-040].wrt
);
822 case 050: case 051: case 052:
823 if (ins
->oprs
[c
-050].segment
!= segment
)
824 errfunc (ERR_NONFATAL
, "short relative jump outside segment");
825 data
= ins
->oprs
[c
-050].offset
- insn_end
;
826 if (data
> 127 || data
< -128)
827 errfunc (ERR_NONFATAL
, "short jump is out of range");
829 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
833 case 060: case 061: case 062:
834 if (ins
->oprs
[c
-060].segment
!= segment
) {
835 data
= ins
->oprs
[c
-060].offset
;
836 out (offset
, segment
, &data
, OUT_REL2ADR
+insn_end
-offset
,
837 ins
->oprs
[c
-060].segment
, ins
->oprs
[c
-060].wrt
);
839 data
= ins
->oprs
[c
-060].offset
- insn_end
;
840 out (offset
, segment
, &data
,
841 OUT_ADDRESS
+2, NO_SEG
, NO_SEG
);
846 case 064: case 065: case 066:
847 size
= ((ins
->oprs
[c
-064].addr_size
?
848 ins
->oprs
[c
-064].addr_size
: bits
) == 16 ? 2 : 4);
849 if (ins
->oprs
[c
-064].segment
!= segment
) {
850 data
= ins
->oprs
[c
-064].offset
;
851 size
= (bits
== 16 ? OUT_REL2ADR
: OUT_REL4ADR
);
852 out (offset
, segment
, &data
, size
+insn_end
-offset
,
853 ins
->oprs
[c
-064].segment
, ins
->oprs
[c
-064].wrt
);
854 size
= (bits
== 16 ? 2 : 4);
856 data
= ins
->oprs
[c
-064].offset
- insn_end
;
857 out (offset
, segment
, &data
,
858 OUT_ADDRESS
+size
, NO_SEG
, NO_SEG
);
863 case 070: case 071: case 072:
864 if (ins
->oprs
[c
-070].segment
!= segment
) {
865 data
= ins
->oprs
[c
-070].offset
;
866 out (offset
, segment
, &data
, OUT_REL4ADR
+insn_end
-offset
,
867 ins
->oprs
[c
-070].segment
, ins
->oprs
[c
-070].wrt
);
869 data
= ins
->oprs
[c
-070].offset
- insn_end
;
870 out (offset
, segment
, &data
,
871 OUT_ADDRESS
+4, NO_SEG
, NO_SEG
);
876 case 0130: case 0131: case 0132:
877 data
= ins
->oprs
[c
-0130].offset
;
878 if (is_sbyte(ins
, c
-0130, 16)) {
879 out (offset
, segment
, &data
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
882 if (ins
->oprs
[c
-0130].segment
== NO_SEG
&&
883 ins
->oprs
[c
-0130].wrt
== NO_SEG
&&
884 (data
< -65536L || data
> 65535L)) {
885 errfunc (ERR_WARNING
, "word value exceeds bounds");
887 out (offset
, segment
, &data
, OUT_ADDRESS
+2,
888 ins
->oprs
[c
-0130].segment
, ins
->oprs
[c
-0130].wrt
);
893 case 0133: case 0134: case 0135:
896 if (is_sbyte(ins
, c
-0133, 16)) bytes
[0] |= 2; /* s-bit */
897 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
901 case 0140: case 0141: case 0142:
902 data
= ins
->oprs
[c
-0140].offset
;
903 if (is_sbyte(ins
, c
-0140, 32)) {
904 out (offset
, segment
, &data
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
907 out (offset
, segment
, &data
, OUT_ADDRESS
+4,
908 ins
->oprs
[c
-0140].segment
, ins
->oprs
[c
-0140].wrt
);
913 case 0143: case 0144: case 0145:
916 if (is_sbyte(ins
, c
-0143, 32)) bytes
[0] |= 2; /* s-bit */
917 out (offset
, segment
, bytes
, OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
921 case 0300: case 0301: case 0302:
922 if (chsize (&ins
->oprs
[c
-0300], bits
)) {
924 out (offset
, segment
, bytes
,
925 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
934 out (offset
, segment
, bytes
,
935 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
944 out (offset
, segment
, bytes
,
945 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
957 out (offset
, segment
, bytes
,
958 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
967 out (offset
, segment
, bytes
,
968 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
978 *bytes
= *codes
++ ^ condval
[ins
->condition
];
979 out (offset
, segment
, bytes
,
980 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
990 out (offset
, segment
, bytes
,
991 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
995 case 0340: case 0341: case 0342:
996 if (ins
->oprs
[0].segment
!= NO_SEG
)
997 errfunc (ERR_PANIC
, "non-constant BSS size in pass two");
999 long size
= ins
->oprs
[0].offset
<< (c
-0340);
1001 out (offset
, segment
, NULL
,
1002 OUT_RESERVE
+size
, NO_SEG
, NO_SEG
);
1007 case 0370: case 0371: case 0372:
1011 *bytes
= bits
==16 ? 3 : 5;
1012 out (offset
, segment
, bytes
,
1013 OUT_RAWDATA
+1, NO_SEG
, NO_SEG
);
1017 default: /* can't do it by 'case' statements */
1018 if (c
>=0100 && c
<=0277) { /* it's an EA */
1024 if (c
<=0177) /* pick rfield from operand b */
1025 rfield
= regval (&ins
->oprs
[c
&7]);
1026 else /* rfield is constant */
1029 if (!process_ea (&ins
->oprs
[(c
>>3)&7], &ea_data
, bits
, rfield
,
1032 errfunc (ERR_NONFATAL
, "invalid effective address");
1036 *p
++ = ea_data
.modrm
;
1037 if (ea_data
.sib_present
)
1041 out (offset
, segment
, bytes
, OUT_RAWDATA
+ s
,
1044 switch (ea_data
.bytes
) {
1048 if (ins
->oprs
[(c
>>3)&7].segment
!= NO_SEG
) {
1049 data
= ins
->oprs
[(c
>>3)&7].offset
;
1050 out (offset
, segment
, &data
, OUT_ADDRESS
+1,
1051 ins
->oprs
[(c
>>3)&7].segment
,
1052 ins
->oprs
[(c
>>3)&7].wrt
);
1054 *bytes
= ins
->oprs
[(c
>>3)&7].offset
;
1055 out (offset
, segment
, bytes
, OUT_RAWDATA
+1,
1062 data
= ins
->oprs
[(c
>>3)&7].offset
;
1063 out (offset
, segment
, &data
,
1064 OUT_ADDRESS
+ea_data
.bytes
,
1065 ins
->oprs
[(c
>>3)&7].segment
, ins
->oprs
[(c
>>3)&7].wrt
);
1071 errfunc (ERR_PANIC
, "internal instruction table corrupt"
1072 ": instruction code 0x%02X given", c
);
1076 static int regval (operand
*o
)
1078 switch (o
->basereg
) {
1079 case R_EAX
: case R_AX
: case R_AL
: case R_ES
: case R_CR0
: case R_DR0
:
1080 case R_ST0
: case R_MM0
: case R_XMM0
:
1082 case R_ECX
: case R_CX
: case R_CL
: case R_CS
: case R_DR1
: case R_ST1
:
1083 case R_MM1
: case R_XMM1
:
1085 case R_EDX
: case R_DX
: case R_DL
: case R_SS
: case R_CR2
: case R_DR2
:
1086 case R_ST2
: case R_MM2
: case R_XMM2
:
1088 case R_EBX
: case R_BX
: case R_BL
: case R_DS
: case R_CR3
: case R_DR3
:
1089 case R_TR3
: case R_ST3
: case R_MM3
: case R_XMM3
:
1091 case R_ESP
: case R_SP
: case R_AH
: case R_FS
: case R_CR4
: case R_TR4
:
1092 case R_ST4
: case R_MM4
: case R_XMM4
:
1094 case R_EBP
: case R_BP
: case R_CH
: case R_GS
: case R_TR5
: case R_ST5
:
1095 case R_MM5
: case R_XMM5
:
1097 case R_ESI
: case R_SI
: case R_DH
: case R_DR6
: case R_TR6
: case R_ST6
:
1098 case R_MM6
: case R_XMM6
:
1100 case R_EDI
: case R_DI
: case R_BH
: case R_DR7
: case R_TR7
: case R_ST7
:
1101 case R_MM7
: case R_XMM7
:
1103 default: /* panic */
1104 errfunc (ERR_PANIC
, "invalid register operand given to regval()");
1109 static int matches (struct itemplate
*itemp
, insn
*instruction
)
1111 int i
, size
[3], asize
, oprs
, ret
;
1118 if (itemp
->opcode
!= instruction
->opcode
) return 0;
1121 * Count the operands
1123 if (itemp
->operands
!= instruction
->operands
) return 0;
1126 * Check that no spurious colons or TOs are present
1128 for (i
=0; i
<itemp
->operands
; i
++)
1129 if (instruction
->oprs
[i
].type
& ~itemp
->opd
[i
] & (COLON
|TO
))
1133 * Check that the operand flags all match up
1135 for (i
=0; i
<itemp
->operands
; i
++)
1136 if (itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
||
1137 ((itemp
->opd
[i
] & SIZE_MASK
) &&
1138 ((itemp
->opd
[i
] ^ instruction
->oprs
[i
].type
) & SIZE_MASK
)))
1140 if ((itemp
->opd
[i
] & ~instruction
->oprs
[i
].type
& NON_SIZE
) ||
1141 (instruction
->oprs
[i
].type
& SIZE_MASK
))
1149 * Check operand sizes
1151 if (itemp
->flags
& IF_ARMASK
) {
1152 size
[0] = size
[1] = size
[2] = 0;
1154 switch (itemp
->flags
& IF_ARMASK
) {
1155 case IF_AR0
: i
= 0; break;
1156 case IF_AR1
: i
= 1; break;
1157 case IF_AR2
: i
= 2; break;
1158 default: break; /* Shouldn't happen */
1160 if (itemp
->flags
& IF_SB
) {
1162 } else if (itemp
->flags
& IF_SW
) {
1164 } else if (itemp
->flags
& IF_SD
) {
1169 if (itemp
->flags
& IF_SB
) {
1171 oprs
= itemp
->operands
;
1172 } else if (itemp
->flags
& IF_SW
) {
1174 oprs
= itemp
->operands
;
1175 } else if (itemp
->flags
& IF_SD
) {
1177 oprs
= itemp
->operands
;
1179 size
[0] = size
[1] = size
[2] = asize
;
1182 if (itemp
->flags
& (IF_SM
| IF_SM2
)) {
1183 oprs
= (itemp
->flags
& IF_SM2
? 2 : itemp
->operands
);
1185 for (i
=0; i
<oprs
; i
++) {
1186 if ( (asize
= itemp
->opd
[i
] & SIZE_MASK
) != 0) {
1188 for (j
=0; j
<oprs
; j
++)
1194 oprs
= itemp
->operands
;
1197 for (i
=0; i
<itemp
->operands
; i
++)
1198 if (!(itemp
->opd
[i
] & SIZE_MASK
) &&
1199 (instruction
->oprs
[i
].type
& SIZE_MASK
& ~size
[i
]))
1204 * Check template is okay at the set cpu level
1206 if ((itemp
->flags
& IF_PLEVEL
) > cpu
) return 3;
1209 * Check if special handling needed for Jumps
1211 if ((unsigned char)(itemp
->code
[0]) >= 0370) return 99;
1216 static ea
*process_ea (operand
*input
, ea
*output
, int addrbits
, int rfield
,
1219 if (!(REGISTER
& ~input
->type
)) { /* it's a single register */
1220 static int regs
[] = {
1221 R_AL
, R_CL
, R_DL
, R_BL
, R_AH
, R_CH
, R_DH
, R_BH
,
1222 R_AX
, R_CX
, R_DX
, R_BX
, R_SP
, R_BP
, R_SI
, R_DI
,
1223 R_EAX
, R_ECX
, R_EDX
, R_EBX
, R_ESP
, R_EBP
, R_ESI
, R_EDI
,
1224 R_MM0
, R_MM1
, R_MM2
, R_MM3
, R_MM4
, R_MM5
, R_MM6
, R_MM7
,
1225 R_XMM0
, R_XMM1
, R_XMM2
, R_XMM3
, R_XMM4
, R_XMM5
, R_XMM6
, R_XMM7
1229 for (i
=0; i
<elements(regs
); i
++)
1230 if (input
->basereg
== regs
[i
]) break;
1231 if (i
<elements(regs
)) {
1232 output
->sib_present
= FALSE
;/* no SIB necessary */
1233 output
->bytes
= 0; /* no offset necessary either */
1234 output
->modrm
= 0xC0 | (rfield
<< 3) | (i
& 7);
1238 } else { /* it's a memory reference */
1239 if (input
->basereg
==-1 && (input
->indexreg
==-1 || input
->scale
==0)) {
1240 /* it's a pure offset */
1241 if (input
->addr_size
)
1242 addrbits
= input
->addr_size
;
1243 output
->sib_present
= FALSE
;
1244 output
->bytes
= (addrbits
==32 ? 4 : 2);
1245 output
->modrm
= (addrbits
==32 ? 5 : 6) | (rfield
<< 3);
1247 else { /* it's an indirection */
1248 int i
=input
->indexreg
, b
=input
->basereg
, s
=input
->scale
;
1249 long o
=input
->offset
, seg
=input
->segment
;
1250 int hb
=input
->hintbase
, ht
=input
->hinttype
;
1253 if (s
==0) i
= -1; /* make this easy, at least */
1255 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1256 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1257 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1258 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
) {
1259 /* it must be a 32-bit memory reference. Firstly we have
1260 * to check that all registers involved are type Exx. */
1261 if (i
!=-1 && i
!=R_EAX
&& i
!=R_EBX
&& i
!=R_ECX
&& i
!=R_EDX
1262 && i
!=R_EBP
&& i
!=R_ESP
&& i
!=R_ESI
&& i
!=R_EDI
)
1264 if (b
!=-1 && b
!=R_EAX
&& b
!=R_EBX
&& b
!=R_ECX
&& b
!=R_EDX
1265 && b
!=R_EBP
&& b
!=R_ESP
&& b
!=R_ESI
&& b
!=R_EDI
)
1268 /* While we're here, ensure the user didn't specify WORD. */
1269 if (input
->addr_size
== 16)
1272 /* now reorganise base/index */
1273 if (s
== 1 && b
!= i
&& b
!= -1 && i
!= -1 &&
1274 ((hb
==b
&&ht
==EAH_NOTBASE
) || (hb
==i
&&ht
==EAH_MAKEBASE
)))
1275 t
= b
, b
= i
, i
= t
; /* swap if hints say so */
1276 if (b
==i
) /* convert EAX+2*EAX to 3*EAX */
1278 if (b
==-1 && s
==1 && !(hb
== i
&& ht
== EAH_NOTBASE
))
1279 b
= i
, i
= -1; /* make single reg base, unless hint */
1280 if (((s
==2 && i
!=R_ESP
&& !(input
->eaflags
& EAF_TIMESTWO
)) ||
1281 s
==3 || s
==5 || s
==9) && b
==-1)
1282 b
= i
, s
--; /* convert 3*EAX to EAX+2*EAX */
1283 if (s
==1 && i
==R_ESP
) /* swap ESP into base if scale is 1 */
1285 if (i
==R_ESP
|| (s
!=1 && s
!=2 && s
!=4 && s
!=8 && i
!=-1))
1286 return NULL
; /* wrong, for various reasons */
1288 if (i
==-1 && b
!=R_ESP
) {/* no SIB needed */
1291 case R_EAX
: rm
= 0; break;
1292 case R_ECX
: rm
= 1; break;
1293 case R_EDX
: rm
= 2; break;
1294 case R_EBX
: rm
= 3; break;
1295 case R_EBP
: rm
= 5; break;
1296 case R_ESI
: rm
= 6; break;
1297 case R_EDI
: rm
= 7; break;
1298 case -1: rm
= 5; break;
1299 default: /* should never happen */
1302 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1303 seg
==NO_SEG
&& !forw_ref
&&
1305 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1307 else if (input
->eaflags
& EAF_BYTEOFFS
||
1308 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1309 !(input
->eaflags
& EAF_WORDOFFS
))) {
1315 output
->sib_present
= FALSE
;
1316 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1317 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1319 else { /* we need a SIB */
1320 int mod
, scale
, index
, base
;
1323 case R_EAX
: base
= 0; break;
1324 case R_ECX
: base
= 1; break;
1325 case R_EDX
: base
= 2; break;
1326 case R_EBX
: base
= 3; break;
1327 case R_ESP
: base
= 4; break;
1328 case R_EBP
: case -1: base
= 5; break;
1329 case R_ESI
: base
= 6; break;
1330 case R_EDI
: base
= 7; break;
1331 default: /* then what the smeg is it? */
1332 return NULL
; /* panic */
1336 case R_EAX
: index
= 0; break;
1337 case R_ECX
: index
= 1; break;
1338 case R_EDX
: index
= 2; break;
1339 case R_EBX
: index
= 3; break;
1340 case -1: index
= 4; break;
1341 case R_EBP
: index
= 5; break;
1342 case R_ESI
: index
= 6; break;
1343 case R_EDI
: index
= 7; break;
1344 default: /* then what the smeg is it? */
1345 return NULL
; /* panic */
1350 case 1: scale
= 0; break;
1351 case 2: scale
= 1; break;
1352 case 4: scale
= 2; break;
1353 case 8: scale
= 3; break;
1354 default: /* then what the smeg is it? */
1355 return NULL
; /* panic */
1358 if (b
==-1 || (b
!=R_EBP
&& o
==0 &&
1359 seg
==NO_SEG
&& !forw_ref
&&
1361 (EAF_BYTEOFFS
|EAF_WORDOFFS
))))
1363 else if (input
->eaflags
& EAF_BYTEOFFS
||
1364 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1365 !(input
->eaflags
& EAF_WORDOFFS
)))
1370 output
->sib_present
= TRUE
;
1371 output
->bytes
= (b
==-1 || mod
==2 ? 4 : mod
);
1372 output
->modrm
= (mod
<<6) | (rfield
<<3) | 4;
1373 output
->sib
= (scale
<<6) | (index
<<3) | base
;
1376 else { /* it's 16-bit */
1379 /* check all registers are BX, BP, SI or DI */
1380 if ((b
!=-1 && b
!=R_BP
&& b
!=R_BX
&& b
!=R_SI
&& b
!=R_DI
) ||
1381 (i
!=-1 && i
!=R_BP
&& i
!=R_BX
&& i
!=R_SI
&& i
!=R_DI
))
1384 /* ensure the user didn't specify DWORD */
1385 if (input
->addr_size
== 32)
1388 if (s
!=1 && i
!=-1) return NULL
;/* no can do, in 16-bit EA */
1389 if (b
==-1 && i
!=-1) b
^= i
^= b
^= i
; /* swap them round */
1390 if ((b
==R_SI
|| b
==R_DI
) && i
!=-1)
1391 b
^= i
^= b
^= i
; /* have BX/BP as base, SI/DI index */
1392 if (b
==i
) return NULL
;/* shouldn't ever happen, in theory */
1393 if (i
!=-1 && b
!=-1 &&
1394 (i
==R_BP
|| i
==R_BX
|| b
==R_SI
|| b
==R_DI
))
1395 return NULL
; /* invalid combinations */
1396 if (b
==-1) /* pure offset: handled above */
1397 return NULL
; /* so if it gets to here, panic! */
1401 switch (i
*256 + b
) {
1402 case R_SI
*256+R_BX
: rm
=0; break;
1403 case R_DI
*256+R_BX
: rm
=1; break;
1404 case R_SI
*256+R_BP
: rm
=2; break;
1405 case R_DI
*256+R_BP
: rm
=3; break;
1409 case R_SI
: rm
=4; break;
1410 case R_DI
: rm
=5; break;
1411 case R_BP
: rm
=6; break;
1412 case R_BX
: rm
=7; break;
1414 if (rm
==-1) /* can't happen, in theory */
1415 return NULL
; /* so panic if it does */
1417 if (o
==0 && seg
==NO_SEG
&& !forw_ref
&& rm
!=6 &&
1418 !(input
->eaflags
& (EAF_BYTEOFFS
|EAF_WORDOFFS
)))
1420 else if (input
->eaflags
& EAF_BYTEOFFS
||
1421 (o
>=-128 && o
<=127 && seg
==NO_SEG
&& !forw_ref
&&
1422 !(input
->eaflags
& EAF_WORDOFFS
)))
1427 output
->sib_present
= FALSE
; /* no SIB - it's 16-bit */
1428 output
->bytes
= mod
; /* bytes of offset needed */
1429 output
->modrm
= (mod
<<6) | (rfield
<<3) | rm
;
1433 output
->size
= 1 + output
->sib_present
+ output
->bytes
;
1437 static int chsize (operand
*input
, int addrbits
)
1439 if (!(MEMORY
& ~input
->type
)) {
1440 int i
=input
->indexreg
, b
=input
->basereg
;
1442 if (input
->scale
==0) i
= -1;
1444 if (i
== -1 && b
== -1) /* pure offset */
1445 return (input
->addr_size
!= 0 && input
->addr_size
!= addrbits
);
1447 if (i
==R_EAX
|| i
==R_EBX
|| i
==R_ECX
|| i
==R_EDX
1448 || i
==R_EBP
|| i
==R_ESP
|| i
==R_ESI
|| i
==R_EDI
1449 || b
==R_EAX
|| b
==R_EBX
|| b
==R_ECX
|| b
==R_EDX
1450 || b
==R_EBP
|| b
==R_ESP
|| b
==R_ESI
|| b
==R_EDI
)
1451 return (addrbits
==16);
1453 return (addrbits
==32);