assemble.c
上传用户:yuppie_zhu
上传日期:2007-01-08
资源大小:535k
文件大小:39k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. /* assemble.c   code generation for the Netwide Assembler
  2.  *
  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.
  7.  *
  8.  * the actual codes (C syntax, i.e. octal):
  9.  *             - 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
  14.  *                 on operand 0
  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.  * 2ab          - a ModRM, calculated on EA in operand a, with the spare
  36.  *                 field equal to digit b.
  37.  * 30x          - might be an 0x67 byte, depending on the address size of
  38.  *                 the memory reference in operand x.
  39.  * 310          - indicates fixed 16-bit address size, i.e. optional 0x67.
  40.  * 311          - indicates fixed 32-bit address size, i.e. optional 0x67.
  41.  * 320          - indicates fixed 16-bit operand size, i.e. optional 0x66.
  42.  * 321          - indicates fixed 32-bit operand size, i.e. optional 0x66.
  43.  * 322          - indicates that this instruction is only valid when the
  44.  *                 operand size is the default (instruction to disassembler,
  45.  *                 generates no code in the assembler)
  46.  * 330          - a literal byte follows in the code stream, to be added
  47.  *                 to the condition code value of the instruction.
  48.  * 331  - instruction not valid with REP prefix.  Hint for
  49.  *                 disassembler only; for SSE instructions.
  50.  * 332  - disassemble a rep (0xF3 byte) prefix as repe not rep.
  51.  * 333  - REP prefix (0xF3 byte); for SSE instructions.  Not encoded
  52.  *    as a literal byte in order to aid the disassembler.
  53.  * 340          - reserve <operand 0> bytes of uninitialised storage.
  54.  *                 Operand 0 had better be a segmentless constant.
  55.  */
  56. #include <stdio.h>
  57. #include <string.h>
  58. #include "nasm.h"
  59. #include "nasmlib.h"
  60. #include "assemble.h"
  61. #include "insns.h"
  62. extern struct itemplate *nasm_instructions[];
  63. typedef struct {
  64.     int sib_present;        /* is a SIB byte necessary? */
  65.     int bytes;        /* # of bytes of offset needed */
  66.     int size;        /* lazy - this is sib+bytes+1 */
  67.     unsigned char modrm, sib;        /* the bytes themselves */
  68. } ea;
  69. static efunc errfunc;
  70. static struct ofmt *outfmt;
  71. static ListGen *list;
  72. static long calcsize (long, long, int, insn *, char *);
  73. static void gencode (long, long, int, insn *, char *, long);
  74. static int  regval (operand *o);
  75. static int  matches (struct itemplate *, insn *);
  76. static ea * process_ea (operand *, ea *, int, int, int);
  77. static int  chsize (operand *, int);
  78. /*
  79.  * This routine wrappers the real output format's output routine,
  80.  * in order to pass a copy of the data off to the listing file
  81.  * generator at the same time.
  82.  */
  83. static void out (long offset, long segto, void *data, unsigned long type,
  84.  long segment, long wrt) 
  85. {
  86.     static long lineno;
  87.     static char *lnfname;
  88.     if ((type & OUT_TYPMASK) == OUT_ADDRESS) {
  89. if (segment != NO_SEG || wrt != NO_SEG) {
  90.     /*
  91.      * This address is relocated. We must write it as
  92.      * OUT_ADDRESS, so there's no work to be done here.
  93.      */
  94.     list->output (offset, data, type);
  95. else {
  96.     unsigned char p[4], *q = p;
  97.     /*
  98.      * This is a non-relocated address, and we're going to
  99.      * convert it into RAWDATA format.
  100.      */
  101.     if ((type & OUT_SIZMASK) == 4) {
  102. WRITELONG (q, * (long *) data);
  103. list->output (offset, p, OUT_RAWDATA+4);
  104.     } 
  105.     else {
  106. WRITESHORT (q, * (long *) data);
  107. list->output (offset, p, OUT_RAWDATA+2);
  108.     }
  109. }
  110.     } 
  111.     else if ((type & OUT_TYPMASK) == OUT_RAWDATA) {
  112. list->output (offset, data, type);
  113.     } 
  114.     else if ((type & OUT_TYPMASK) == OUT_RESERVE) {
  115. list->output (offset, NULL, type);
  116.     } 
  117.     else if ((type & OUT_TYPMASK) == OUT_REL2ADR ||
  118.        (type & OUT_TYPMASK) == OUT_REL4ADR) {
  119. list->output (offset, data, type);
  120.     }
  121.     if (src_get(&lineno,&lnfname))
  122. outfmt->current_dfmt->linenum(lnfname,lineno,segto);
  123.     outfmt->output (segto, data, type, segment, wrt);
  124. }
  125. long assemble (long segment, long offset, int bits,
  126.        insn *instruction, struct ofmt *output, efunc error,
  127.        ListGen *listgen) 
  128. {
  129.     struct itemplate *temp;
  130.     int    j;
  131.     int    size_prob;
  132.     long   insn_end;
  133.     long   itimes;
  134.     long   start = offset;
  135.     long   wsize = 0;        /* size for DB etc. */
  136.     errfunc = error;        /* to pass to other functions */
  137.     outfmt = output;        /* likewise */
  138.     list = listgen;        /* and again */
  139.     switch (instruction->opcode) 
  140.     {
  141. case   -1: return 0;
  142. case I_DB: wsize = 1; break;
  143. case I_DW: wsize = 2; break;
  144. case I_DD: wsize = 4; break;
  145. case I_DQ: wsize = 8; break;
  146. case I_DT: wsize = 10; break;
  147.     }
  148.     if (wsize) {
  149. extop  * e;
  150. long   t = instruction->times;
  151. if (t < 0)
  152.     errfunc(ERR_PANIC, "instruction->times < 0 (%ld) in assemble()",t);
  153. while (t--)         /* repeat TIMES times */
  154. {
  155.     for (e = instruction->eops; e; e = e->next) 
  156.     {
  157. if (e->type == EOT_DB_NUMBER) 
  158. {
  159.     if (wsize == 1) {
  160. if (e->segment != NO_SEG)
  161.     errfunc (ERR_NONFATAL,
  162.      "one-byte relocation attempted");
  163. else {
  164.     unsigned char out_byte = e->offset;
  165.     out (offset, segment, &out_byte, OUT_RAWDATA+1,
  166.  NO_SEG, NO_SEG);
  167. }
  168.     } 
  169.     else if (wsize > 5) {
  170. errfunc (ERR_NONFATAL, "integer supplied to a D%c"
  171.  " instruction", wsize==8 ? 'Q' : 'T');
  172.     } 
  173.     else
  174. out (offset, segment, &e->offset,
  175.      OUT_ADDRESS+wsize, e->segment,
  176.      e->wrt);
  177.     offset += wsize;
  178. else if (e->type == EOT_DB_STRING) 
  179. {
  180.     int align;
  181.     out (offset, segment, e->stringval,
  182.  OUT_RAWDATA+e->stringlen, NO_SEG, NO_SEG);
  183.     align = e->stringlen % wsize;
  184.     if (align) {
  185. align = wsize - align;
  186. out (offset, segment, "",
  187.      OUT_RAWDATA+align, NO_SEG, NO_SEG);
  188. }
  189.     offset += e->stringlen + align;
  190. }
  191.     }
  192.     if (t > 0 && t == instruction->times-1) 
  193.     {
  194. /*
  195.  * Dummy call to list->output to give the offset to the
  196.  * listing module.
  197.  */
  198. list->output (offset, NULL, OUT_RAWDATA);
  199. list->uplevel (LIST_TIMES);
  200.     }
  201. }
  202. if (instruction->times > 1)
  203.     list->downlevel (LIST_TIMES);
  204. return offset - start;
  205.     }
  206.     if (instruction->opcode == I_INCBIN) 
  207.     {
  208. static char fname[FILENAME_MAX];
  209. FILE        * fp;
  210. long        len;
  211. len = FILENAME_MAX-1;
  212. if (len > instruction->eops->stringlen)
  213.     len = instruction->eops->stringlen;
  214. strncpy (fname, instruction->eops->stringval, len);
  215. fname[len] = '';
  216. if ( (fp = fopen(fname, "rb")) == NULL)
  217.     error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
  218. else if (fseek(fp, 0L, SEEK_END) < 0)
  219.     error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
  220.    fname);
  221. else 
  222. {
  223.     static char buf[2048];
  224.     long t = instruction->times;
  225.     long base = 0;
  226.     len = ftell (fp);
  227.     if (instruction->eops->next) {
  228. base = instruction->eops->next->offset;
  229. len -= base;
  230. if (instruction->eops->next->next &&
  231.     len > instruction->eops->next->next->offset)
  232.     len = instruction->eops->next->next->offset;
  233.     }
  234.     /*
  235.      * Dummy call to list->output to give the offset to the
  236.      * listing module.
  237.      */
  238.     list->output (offset, NULL, OUT_RAWDATA);
  239.     list->uplevel(LIST_INCBIN);
  240.     while (t--) 
  241.     {
  242. long l;
  243. fseek (fp, base, SEEK_SET);
  244. l = len;
  245. while (l > 0) {
  246.     long m = fread (buf, 1, (l>sizeof(buf)?sizeof(buf):l),
  247.     fp);
  248.     if (!m) {
  249. /*
  250.  * This shouldn't happen unless the file
  251.  * actually changes while we are reading
  252.  * it.
  253.  */
  254. error (ERR_NONFATAL, "`incbin': unexpected EOF while"
  255.        " reading file `%s'", fname);
  256. t=0;  /* Try to exit cleanly */
  257. break;
  258.     }
  259.     out (offset, segment, buf, OUT_RAWDATA+m,
  260.  NO_SEG, NO_SEG);
  261.     l -= m;
  262. }
  263.     }
  264.     list->downlevel(LIST_INCBIN);
  265.     if (instruction->times > 1) {
  266. /*
  267.  * Dummy call to list->output to give the offset to the
  268.  * listing module.
  269.  */
  270. list->output (offset, NULL, OUT_RAWDATA);
  271. list->uplevel(LIST_TIMES);
  272. list->downlevel(LIST_TIMES);
  273.     }
  274.     fclose (fp);
  275.     return instruction->times * len;
  276. }
  277. return 0;        /* if we're here, there's an error */
  278.     }
  279.     size_prob = FALSE;
  280.     temp = nasm_instructions[instruction->opcode];
  281.     while (temp->opcode != -1) {
  282. int m = matches (temp, instruction);
  283. if (m == 100)         /* matches! */
  284. {
  285.     char *codes = temp->code;
  286.     long insn_size = calcsize(segment, offset, bits,
  287.       instruction, codes);
  288.     itimes = instruction->times;
  289.     if (insn_size < 0)        /* shouldn't be, on pass two */
  290.      error (ERR_PANIC, "errors made it through from pass one");
  291.     else while (itimes--) {
  292. insn_end = offset + insn_size;
  293. for (j=0; j<instruction->nprefix; j++) {
  294.     unsigned char c=0;
  295.     switch (instruction->prefixes[j]) {
  296.       case P_LOCK:
  297. c = 0xF0; break;
  298.       case P_REPNE: case P_REPNZ:
  299. c = 0xF2; break;
  300.       case P_REPE: case P_REPZ: case P_REP:
  301. c = 0xF3; break;
  302.       case R_CS: c = 0x2E; break;
  303.       case R_DS: c = 0x3E; break;
  304.       case R_ES: c = 0x26; break;
  305.       case R_FS: c = 0x64; break;
  306.       case R_GS: c = 0x65; break;
  307.       case R_SS: c = 0x36; break;
  308.       case P_A16:
  309. if (bits != 16)
  310.     c = 0x67;
  311. break;
  312.       case P_A32:
  313. if (bits != 32)
  314.     c = 0x67;
  315. break;
  316.       case P_O16:
  317. if (bits != 16)
  318.     c = 0x66;
  319. break;
  320.       case P_O32:
  321. if (bits != 32)
  322.     c = 0x66;
  323. break;
  324.       default:
  325. error (ERR_PANIC,
  326.        "invalid instruction prefix");
  327.     }
  328.     if (c != 0) {
  329. out (offset, segment, &c, OUT_RAWDATA+1,
  330.      NO_SEG, NO_SEG);
  331. offset++;
  332.     }
  333. }
  334. gencode (segment, offset, bits, instruction, codes, insn_end);
  335. offset += insn_size;
  336. if (itimes > 0 && itimes == instruction->times-1) {
  337.     /*
  338.      * Dummy call to list->output to give the offset to the
  339.      * listing module.
  340.      */
  341.     list->output (offset, NULL, OUT_RAWDATA);
  342.     list->uplevel (LIST_TIMES);
  343. }
  344.     }
  345.     if (instruction->times > 1)
  346. list->downlevel (LIST_TIMES);
  347.     return offset - start;
  348. } else if (m > 0) {
  349.     size_prob = m;
  350. }
  351. temp++;
  352.     }
  353.     if (temp->opcode == -1) {        /* didn't match any instruction */
  354. if (size_prob == 1)        /* would have matched, but for size */
  355.     error (ERR_NONFATAL, "operation size not specified");
  356. else if (size_prob == 2)
  357.     error (ERR_NONFATAL, "mismatch in operand sizes");
  358. else
  359.     error (ERR_NONFATAL,
  360.    "invalid combination of opcode and operands");
  361.     }
  362.     return 0;
  363. }
  364. long insn_size (long segment, long offset, int bits,
  365. insn *instruction, efunc error) 
  366. {
  367.     struct itemplate *temp;
  368.     errfunc = error;        /* to pass to other functions */
  369.     if (instruction->opcode == -1)
  370.      return 0;
  371.     if (instruction->opcode == I_DB ||
  372. instruction->opcode == I_DW ||
  373. instruction->opcode == I_DD ||
  374. instruction->opcode == I_DQ ||
  375. instruction->opcode == I_DT) 
  376.     {
  377. extop *e;
  378. long isize, osize, wsize = 0;  /* placate gcc */
  379. isize = 0;
  380. switch (instruction->opcode) 
  381. {
  382.   case I_DB: wsize = 1; break;
  383.   case I_DW: wsize = 2; break;
  384.   case I_DD: wsize = 4; break;
  385.   case I_DQ: wsize = 8; break;
  386.   case I_DT: wsize = 10; break;
  387. }
  388. for (e = instruction->eops; e; e = e->next) 
  389. {
  390.     long align;
  391.     osize = 0;
  392.     if (e->type == EOT_DB_NUMBER)
  393. osize = 1;
  394.     else if (e->type == EOT_DB_STRING)
  395. osize = e->stringlen;
  396.     align = (-osize) % wsize;
  397.     if (align < 0)
  398. align += wsize;
  399.     isize += osize + align;
  400. }
  401. return isize * instruction->times;
  402.     }
  403.     if (instruction->opcode == I_INCBIN) 
  404.     {
  405. char  fname[FILENAME_MAX];
  406. FILE  * fp;
  407. long  len;
  408. len = FILENAME_MAX-1;
  409. if (len > instruction->eops->stringlen)
  410.     len = instruction->eops->stringlen;
  411. strncpy (fname, instruction->eops->stringval, len);
  412. fname[len] = '';
  413. if ( (fp = fopen(fname, "rb")) == NULL )
  414.     error (ERR_NONFATAL, "`incbin': unable to open file `%s'", fname);
  415. else if (fseek(fp, 0L, SEEK_END) < 0)
  416.     error (ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
  417.    fname);
  418. else 
  419. {
  420.     len = ftell (fp);
  421.     fclose (fp);
  422.     if (instruction->eops->next) 
  423.     {
  424. len -= instruction->eops->next->offset;
  425. if (instruction->eops->next->next &&
  426.     len > instruction->eops->next->next->offset)
  427. {
  428.     len = instruction->eops->next->next->offset;
  429. }
  430.     }
  431.     return instruction->times * len;
  432. }
  433. return 0;        /* if we're here, there's an error */
  434.     }
  435.     temp = nasm_instructions[instruction->opcode];
  436.     while (temp->opcode != -1) {
  437. if (matches(temp, instruction) == 100) {
  438.     /* we've matched an instruction. */
  439.     long  isize;
  440.     char  * codes = temp->code;
  441.     int   j;
  442.     isize = calcsize(segment, offset, bits, instruction, codes);
  443.     if (isize < 0)
  444.      return -1;
  445.     for (j = 0; j < instruction->nprefix; j++) 
  446.     {
  447. if ((instruction->prefixes[j] != P_A16 &&
  448.      instruction->prefixes[j] != P_O16 && bits==16) ||
  449.     (instruction->prefixes[j] != P_A32 &&
  450.      instruction->prefixes[j] != P_O32 && bits==32))
  451. {
  452.     isize++;
  453. }
  454.     }
  455.     return isize * instruction->times;
  456. }
  457. temp++;
  458.     }
  459.     return -1;        /* didn't match any instruction */
  460. }
  461. static long calcsize (long segment, long offset, int bits,
  462.       insn *ins, char *codes) 
  463. {
  464.     long           length = 0;
  465.     unsigned char  c;
  466.     (void) segment;  /* Don't warn that this parameter is unused */
  467.     (void) offset;   /* Don't warn that this parameter is unused */
  468.     while (*codes) switch (c = *codes++) {
  469.       case 01: case 02: case 03:
  470. codes += c, length += c; break;
  471.       case 04: case 05: case 06: case 07:
  472. length++; break;
  473.       case 010: case 011: case 012:
  474. codes++, length++; break;
  475.       case 017:
  476. length++; break;
  477.       case 014: case 015: case 016:
  478. length++; break;
  479.       case 020: case 021: case 022:
  480. length++; break;
  481.       case 024: case 025: case 026:
  482. length++; break;
  483.       case 030: case 031: case 032:
  484. length += 2; break;
  485.       case 034: case 035: case 036:
  486. length += ((ins->oprs[c-034].addr_size ?
  487.     ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4); break;
  488.       case 037:
  489. length += 2; break;
  490.       case 040: case 041: case 042:
  491. length += 4; break;
  492.       case 050: case 051: case 052:
  493. length++; break;
  494.       case 060: case 061: case 062:
  495. length += 2; break;
  496.       case 064: case 065: case 066:
  497. length += ((ins->oprs[c-064].addr_size ?
  498.     ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4); break;
  499.       case 070: case 071: case 072:
  500. length += 4; break;
  501.       case 0300: case 0301: case 0302:
  502. length += chsize (&ins->oprs[c-0300], bits);
  503. break;
  504.       case 0310:
  505. length += (bits==32);
  506. break;
  507.       case 0311:
  508. length += (bits==16);
  509. break;
  510.       case 0312:
  511. break;
  512.       case 0320:
  513. length += (bits==32);
  514. break;
  515.       case 0321:
  516. length += (bits==16);
  517. break;
  518.       case 0322:
  519. break;
  520.       case 0330:
  521. codes++, length++; break;
  522.       case 0331:
  523.       case 0332:
  524. break;
  525.       case 0333:
  526. length++; break;
  527.       case 0340: case 0341: case 0342:
  528. if (ins->oprs[0].segment != NO_SEG)
  529.     errfunc (ERR_NONFATAL, "attempt to reserve non-constant"
  530.      " quantity of BSS space");
  531. else
  532.     length += ins->oprs[0].offset << (c-0340);
  533. break;
  534.       default:        /* can't do it by 'case' statements */
  535. if (c>=0100 && c<=0277) {      /* it's an EA */
  536.     ea ea_data;
  537.     if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, 0,
  538.      ins->forw_ref)) {
  539.      errfunc (ERR_NONFATAL, "invalid effective address");
  540. return -1;
  541.     } else
  542.      length += ea_data.size;
  543. } else
  544.     errfunc (ERR_PANIC, "internal instruction table corrupt"
  545.      ": instruction code 0x%02X given", c);
  546.     }
  547.     return length;
  548. }
  549. static void gencode (long segment, long offset, int bits,
  550.      insn *ins, char *codes, long insn_end) 
  551. {
  552.     static char condval[] = { /* conditional opcodes */
  553. 0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
  554. 0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
  555. 0x0, 0xA, 0xA, 0xB, 0x8, 0x4
  556.     };
  557.     unsigned char c;
  558.     unsigned char bytes[4];
  559.     long          data, size;
  560.     while (*codes)
  561. switch (c = *codes++) 
  562. {
  563. case 01: case 02: case 03:
  564.     out (offset, segment, codes, OUT_RAWDATA+c, NO_SEG, NO_SEG);
  565.     codes += c;
  566.     offset += c;
  567.     break;
  568. case 04: case 06:
  569.     switch (ins->oprs[0].basereg) 
  570.     {
  571.     case R_CS: 
  572. bytes[0] = 0x0E + (c == 0x04 ? 1 : 0); break;
  573.     case R_DS: 
  574. bytes[0] = 0x1E + (c == 0x04 ? 1 : 0); break;
  575.     case R_ES: 
  576. bytes[0] = 0x06 + (c == 0x04 ? 1 : 0); break;
  577.     case R_SS: 
  578. bytes[0] = 0x16 + (c == 0x04 ? 1 : 0); break;
  579.     default:
  580.                 errfunc (ERR_PANIC, "bizarre 8086 segment register received");
  581.     }
  582.     out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
  583.     offset++;
  584.     break;
  585. case 05: case 07:
  586.     switch (ins->oprs[0].basereg) {
  587.     case R_FS: bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0); break;
  588.     case R_GS: bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0); break;
  589.     default:
  590.                 errfunc (ERR_PANIC, "bizarre 386 segment register received");
  591.     }
  592.     out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
  593.     offset++;
  594.     break;
  595. case 010: case 011: case 012:
  596.     bytes[0] = *codes++ + regval(&ins->oprs[c-010]);
  597.     out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
  598.     offset += 1;
  599.     break;
  600. case 017:
  601.     bytes[0] = 0;
  602.     out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
  603.     offset += 1;
  604.     break;
  605. case 014: case 015: case 016:
  606.     if (ins->oprs[c-014].offset < -128 
  607. || ins->oprs[c-014].offset > 127)
  608.     {
  609. errfunc (ERR_WARNING, "signed byte value exceeds bounds");
  610.     }
  611.     if (ins->oprs[c-014].segment != NO_SEG) 
  612.     {
  613. data = ins->oprs[c-014].offset;
  614. out (offset, segment, &data, OUT_ADDRESS+1,
  615.      ins->oprs[c-014].segment, ins->oprs[c-014].wrt);
  616.     } 
  617.     else {
  618. bytes[0] = ins->oprs[c-014].offset;
  619. out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
  620.     }
  621.     offset += 1;
  622.     break;
  623. case 020: case 021: case 022:
  624.     if (ins->oprs[c-020].offset < -256 
  625. || ins->oprs[c-020].offset > 255)
  626.     {
  627. errfunc (ERR_WARNING, "byte value exceeds bounds");
  628.     }
  629.     if (ins->oprs[c-020].segment != NO_SEG) {
  630. data = ins->oprs[c-020].offset;
  631. out (offset, segment, &data, OUT_ADDRESS+1,
  632.      ins->oprs[c-020].segment, ins->oprs[c-020].wrt);
  633.     } 
  634.     else {
  635. bytes[0] = ins->oprs[c-020].offset;
  636. out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
  637.     }
  638.     offset += 1;
  639.     break;
  640. case 024: case 025: case 026:
  641.     if (ins->oprs[c-024].offset < 0 || ins->oprs[c-024].offset > 255)
  642. errfunc (ERR_WARNING, "unsigned byte value exceeds bounds");
  643.     if (ins->oprs[c-024].segment != NO_SEG) {
  644. data = ins->oprs[c-024].offset;
  645. out (offset, segment, &data, OUT_ADDRESS+1,
  646.      ins->oprs[c-024].segment, ins->oprs[c-024].wrt);
  647.     }
  648.     else {
  649. bytes[0] = ins->oprs[c-024].offset;
  650. out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
  651.     }
  652.     offset += 1;
  653.     break;
  654. case 030: case 031: case 032:
  655.     if (ins->oprs[c-030].segment == NO_SEG &&
  656. ins->oprs[c-030].wrt == NO_SEG &&
  657. (ins->oprs[c-030].offset < -65536L ||
  658.  ins->oprs[c-030].offset > 65535L))
  659.     {
  660. errfunc (ERR_WARNING, "word value exceeds bounds");
  661.     }
  662.     data = ins->oprs[c-030].offset;
  663.     out (offset, segment, &data, OUT_ADDRESS+2,
  664.  ins->oprs[c-030].segment, ins->oprs[c-030].wrt);
  665.     offset += 2;
  666.     break;
  667. case 034: case 035: case 036:
  668.     data = ins->oprs[c-034].offset;
  669.     size = ((ins->oprs[c-034].addr_size ?
  670.      ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4);
  671.     if (size==16 && (data < -65536L || data > 65535L))
  672. errfunc (ERR_WARNING, "word value exceeds bounds");
  673.     out (offset, segment, &data, OUT_ADDRESS+size,
  674.  ins->oprs[c-034].segment, ins->oprs[c-034].wrt);
  675.     offset += size;
  676.     break;
  677. case 037:
  678.     if (ins->oprs[0].segment == NO_SEG)
  679. errfunc (ERR_NONFATAL, "value referenced by FAR is not"
  680.  " relocatable");
  681.     data = 0L;
  682.     out (offset, segment, &data, OUT_ADDRESS+2,
  683.  outfmt->segbase(1+ins->oprs[0].segment),
  684.  ins->oprs[0].wrt);
  685.     offset += 2;
  686. break;
  687. case 040: case 041: case 042:
  688.     data = ins->oprs[c-040].offset;
  689.     out (offset, segment, &data, OUT_ADDRESS+4,
  690.  ins->oprs[c-040].segment, ins->oprs[c-040].wrt);
  691.     offset += 4;
  692.     break;
  693. case 050: case 051: case 052:
  694.     if (ins->oprs[c-050].segment != segment)
  695. errfunc (ERR_NONFATAL, "short relative jump outside segment");
  696.     data = ins->oprs[c-050].offset - insn_end;
  697.     if (data > 127 || data < -128)
  698. errfunc (ERR_NONFATAL, "short jump is out of range");
  699.     bytes[0] = data;
  700.     out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG);
  701.     offset += 1;
  702.     break;
  703. case 060: case 061: case 062:
  704.     if (ins->oprs[c-060].segment != segment) {
  705. data = ins->oprs[c-060].offset;
  706. out (offset, segment, &data, OUT_REL2ADR+insn_end-offset,
  707.      ins->oprs[c-060].segment, ins->oprs[c-060].wrt);
  708.     } else {
  709. data = ins->oprs[c-060].offset - insn_end;
  710. out (offset, segment, &data,
  711.      OUT_ADDRESS+2, NO_SEG, NO_SEG);
  712.     }
  713.     offset += 2;
  714.     break;
  715. case 064: case 065: case 066:
  716.     size = ((ins->oprs[c-064].addr_size ?
  717.      ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4);
  718.     if (ins->oprs[c-064].segment != segment) {
  719. data = ins->oprs[c-064].offset;
  720. size = (bits == 16 ? OUT_REL2ADR : OUT_REL4ADR);
  721. out (offset, segment, &data, size+insn_end-offset,
  722.      ins->oprs[c-064].segment, ins->oprs[c-064].wrt);
  723. size = (bits == 16 ? 2 : 4);
  724.     } else {
  725. data = ins->oprs[c-064].offset - insn_end;
  726. out (offset, segment, &data,
  727.      OUT_ADDRESS+size, NO_SEG, NO_SEG);
  728.     }
  729.     offset += size;
  730.     break;
  731. case 070: case 071: case 072:
  732.     if (ins->oprs[c-070].segment != segment) {
  733. data = ins->oprs[c-070].offset;
  734. out (offset, segment, &data, OUT_REL4ADR+insn_end-offset,
  735.      ins->oprs[c-070].segment, ins->oprs[c-070].wrt);
  736.     } else {
  737. data = ins->oprs[c-070].offset - insn_end;
  738. out (offset, segment, &data,
  739.      OUT_ADDRESS+4, NO_SEG, NO_SEG);
  740.     }
  741.     offset += 4;
  742.     break;
  743. case 0300: case 0301: case 0302:
  744.     if (chsize (&ins->oprs[c-0300], bits)) {
  745. *bytes = 0x67;
  746. out (offset, segment, bytes,
  747.      OUT_RAWDATA+1, NO_SEG, NO_SEG);
  748. offset += 1;
  749.     } else
  750. offset += 0;
  751.     break;
  752. case 0310:
  753.     if (bits==32) {
  754. *bytes = 0x67;
  755. out (offset, segment, bytes,
  756.      OUT_RAWDATA+1, NO_SEG, NO_SEG);
  757. offset += 1;
  758.     } else
  759. offset += 0;
  760.     break;
  761. case 0311:
  762.     if (bits==16) {
  763. *bytes = 0x67;
  764. out (offset, segment, bytes,
  765.      OUT_RAWDATA+1, NO_SEG, NO_SEG);
  766. offset += 1;
  767.     } else
  768. offset += 0;
  769.     break;
  770. case 0312:
  771.     break;
  772. case 0320:
  773.     if (bits==32) {
  774. *bytes = 0x66;
  775. out (offset, segment, bytes,
  776.      OUT_RAWDATA+1, NO_SEG, NO_SEG);
  777. offset += 1;
  778.     } else
  779. offset += 0;
  780.     break;
  781. case 0321:
  782.     if (bits==16) {
  783. *bytes = 0x66;
  784. out (offset, segment, bytes,
  785.      OUT_RAWDATA+1, NO_SEG, NO_SEG);
  786. offset += 1;
  787.     } else
  788. offset += 0;
  789.     break;
  790. case 0322:
  791.     break;
  792. case 0330:
  793.     *bytes = *codes++ + condval[ins->condition];
  794.     out (offset, segment, bytes,
  795.  OUT_RAWDATA+1, NO_SEG, NO_SEG);
  796.     offset += 1;
  797.     break;
  798. case 0331:
  799. case 0332:
  800.     break;
  801. case 0333:
  802.     *bytes = 0xF3;
  803.     out (offset, segment, bytes,
  804.  OUT_RAWDATA+1, NO_SEG, NO_SEG);
  805.     offset += 1;
  806.     break;
  807. case 0340: case 0341: case 0342:
  808.     if (ins->oprs[0].segment != NO_SEG)
  809. errfunc (ERR_PANIC, "non-constant BSS size in pass two");
  810.     else {
  811. long size = ins->oprs[0].offset << (c-0340);
  812. if (size > 0)
  813.     out (offset, segment, NULL,
  814.  OUT_RESERVE+size, NO_SEG, NO_SEG);
  815. offset += size;
  816.     }
  817.     break;
  818. default:                /* can't do it by 'case' statements */
  819.     if (c>=0100 && c<=0277) {      /* it's an EA */
  820. ea ea_data;
  821. int rfield;
  822. unsigned char *p;
  823. long s;
  824. if (c<=0177)        /* pick rfield from operand b */
  825.     rfield = regval (&ins->oprs[c&7]);
  826. else         /* rfield is constant */
  827.     rfield = c & 7;
  828. if (!process_ea (&ins->oprs[(c>>3)&7], &ea_data, bits, rfield,
  829.  ins->forw_ref))
  830. {
  831.     errfunc (ERR_NONFATAL, "invalid effective address");
  832. }
  833. p = bytes;
  834. *p++ = ea_data.modrm;
  835. if (ea_data.sib_present)
  836.     *p++ = ea_data.sib;
  837. s = p-bytes;
  838. out (offset, segment, bytes, OUT_RAWDATA + s,
  839.      NO_SEG, NO_SEG);
  840. switch (ea_data.bytes) {
  841. case 0:
  842.     break;
  843. case 1:
  844.     if (ins->oprs[(c>>3)&7].segment != NO_SEG) {
  845. data = ins->oprs[(c>>3)&7].offset;
  846. out (offset, segment, &data, OUT_ADDRESS+1,
  847.      ins->oprs[(c>>3)&7].segment,
  848.      ins->oprs[(c>>3)&7].wrt);
  849.     } else {
  850. *bytes = ins->oprs[(c>>3)&7].offset;
  851. out (offset, segment, bytes, OUT_RAWDATA+1,
  852.      NO_SEG, NO_SEG);
  853.     }
  854.     s++;
  855.     break;
  856. case 2:
  857. case 4:
  858.     data = ins->oprs[(c>>3)&7].offset;
  859.     out (offset, segment, &data,
  860.  OUT_ADDRESS+ea_data.bytes,
  861.  ins->oprs[(c>>3)&7].segment, ins->oprs[(c>>3)&7].wrt);
  862.     s += ea_data.bytes;
  863.     break;
  864. }
  865. offset += s;
  866.     } else
  867. errfunc (ERR_PANIC, "internal instruction table corrupt"
  868.      ": instruction code 0x%02X given", c);
  869. }
  870. }
  871. static int regval (operand *o) 
  872. {
  873.     switch (o->basereg) {
  874.       case R_EAX: case R_AX: case R_AL: case R_ES: case R_CR0: case R_DR0:
  875.       case R_ST0: case R_MM0: case R_XMM0:
  876. return 0;
  877.       case R_ECX: case R_CX: case R_CL: case R_CS: case R_DR1: case R_ST1:
  878.       case R_MM1: case R_XMM1:
  879. return 1;
  880.       case R_EDX: case R_DX: case R_DL: case R_SS: case R_CR2: case R_DR2:
  881.       case R_ST2: case R_MM2:  case R_XMM2:
  882. return 2;
  883.       case R_EBX: case R_BX: case R_BL: case R_DS: case R_CR3: case R_DR3:
  884.       case R_TR3: case R_ST3: case R_MM3:  case R_XMM3:
  885. return 3;
  886.       case R_ESP: case R_SP: case R_AH: case R_FS: case R_CR4: case R_TR4:
  887.       case R_ST4: case R_MM4:  case R_XMM4:
  888. return 4;
  889.       case R_EBP: case R_BP: case R_CH: case R_GS: case R_TR5: case R_ST5:
  890.       case R_MM5:  case R_XMM5:
  891. return 5;
  892.       case R_ESI: case R_SI: case R_DH: case R_DR6: case R_TR6: case R_ST6:
  893.       case R_MM6:  case R_XMM6:
  894. return 6;
  895.       case R_EDI: case R_DI: case R_BH: case R_DR7: case R_TR7: case R_ST7:
  896.       case R_MM7:  case R_XMM7:
  897. return 7;
  898.       default:        /* panic */
  899.         errfunc (ERR_PANIC, "invalid register operand given to regval()");
  900. return 0;
  901.     }
  902. }
  903. static int matches (struct itemplate *itemp, insn *instruction) 
  904. {
  905.     int i, size[3], asize, oprs, ret;
  906.     ret = 100;
  907.     /*
  908.      * Check the opcode
  909.      */
  910.     if (itemp->opcode != instruction->opcode) return 0;
  911.     /*
  912.      * Count the operands
  913.      */
  914.     if (itemp->operands != instruction->operands) return 0;
  915.     /*
  916.      * Check that no spurious colons or TOs are present
  917.      */
  918.     for (i=0; i<itemp->operands; i++)
  919. if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON|TO))
  920.     return 0;
  921.     /*
  922.      * Check that the operand flags all match up
  923.      */
  924.     for (i=0; i<itemp->operands; i++)
  925. if (itemp->opd[i] & ~instruction->oprs[i].type ||
  926.     ((itemp->opd[i] & SIZE_MASK) &&
  927.      ((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK)))
  928. {
  929.     if ((itemp->opd[i] & ~instruction->oprs[i].type & NON_SIZE) ||
  930. (instruction->oprs[i].type & SIZE_MASK))
  931. return 0;
  932.     else
  933. ret = 1;
  934. }
  935.     /*
  936.      * Check operand sizes
  937.      */
  938.     if (itemp->flags & IF_ARMASK) {
  939.       size[0] = size[1] = size[2] = 0;
  940.       switch (itemp->flags & IF_ARMASK) {
  941.       case IF_AR0: i = 0; break;
  942.       case IF_AR1: i = 1; break;
  943.       case IF_AR2: i = 2; break;
  944.       default:     break; /* Shouldn't happen */
  945.       }
  946.       if (itemp->flags & IF_SB) {
  947. size[i] = BITS8;
  948.       } else if (itemp->flags & IF_SW) {
  949. size[i] = BITS16;
  950.       } else if (itemp->flags & IF_SD) {
  951. size[i] = BITS32;
  952.       }
  953.     } else {
  954.       asize = 0;
  955.       if (itemp->flags & IF_SB) {
  956. asize = BITS8;
  957. oprs = itemp->operands;
  958.       } else if (itemp->flags & IF_SW) {
  959. asize = BITS16;
  960. oprs = itemp->operands;
  961.       } else if (itemp->flags & IF_SD) {
  962. asize = BITS32;
  963. oprs = itemp->operands;
  964.       }
  965.       size[0] = size[1] = size[2] = asize;
  966.     }
  967.     if (itemp->flags & (IF_SM | IF_SM2)) {
  968.       oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
  969.       asize = 0;
  970.       for (i=0; i<oprs; i++) {
  971. if ( (asize = itemp->opd[i] & SIZE_MASK) != 0) {
  972.   int j;
  973.   for (j=0; j<oprs; j++)
  974.     size[j] = asize;
  975.   break;
  976. }
  977.       }
  978.     } else {
  979.       oprs = itemp->operands;
  980.     }
  981.     for (i=0; i<itemp->operands; i++)
  982. if (!(itemp->opd[i] & SIZE_MASK) &&
  983.     (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
  984.     ret = 2;
  985.     return ret;
  986. }
  987. static ea *process_ea (operand *input, ea *output, int addrbits, int rfield,
  988.        int forw_ref) 
  989. {
  990.     if (!(REGISTER & ~input->type)) {  /* it's a single register */
  991. static int regs[] = {
  992.   R_AL,   R_CL,   R_DL,   R_BL,   R_AH,   R_CH,   R_DH,   R_BH,
  993.   R_AX,   R_CX,   R_DX,   R_BX,   R_SP,   R_BP,   R_SI,   R_DI,
  994.   R_EAX,  R_ECX,  R_EDX,  R_EBX,  R_ESP,  R_EBP,  R_ESI,  R_EDI,
  995.   R_MM0,  R_MM1,  R_MM2,  R_MM3,  R_MM4,  R_MM5,  R_MM6,  R_MM7,
  996.   R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7
  997. };
  998. int i;
  999. for (i=0; i<elements(regs); i++)
  1000.     if (input->basereg == regs[i]) break;
  1001. if (i<elements(regs)) {
  1002.     output->sib_present = FALSE;/* no SIB necessary */
  1003.     output->bytes = 0;        /* no offset necessary either */
  1004.             output->modrm = 0xC0 | (rfield << 3) | (i & 7);
  1005. else
  1006.     return NULL;
  1007.     } else {        /* it's a memory reference */
  1008. if (input->basereg==-1 && (input->indexreg==-1 || input->scale==0)) {
  1009.     /* it's a pure offset */
  1010.     if (input->addr_size)
  1011. addrbits = input->addr_size;
  1012.     output->sib_present = FALSE;
  1013.     output->bytes = (addrbits==32 ? 4 : 2);
  1014.     output->modrm = (addrbits==32 ? 5 : 6) | (rfield << 3);
  1015. else {        /* it's an indirection */
  1016.     int i=input->indexreg, b=input->basereg, s=input->scale;
  1017.     long o=input->offset, seg=input->segment;
  1018.     int hb=input->hintbase, ht=input->hinttype;
  1019.     int t;
  1020.     if (s==0) i = -1;        /* make this easy, at least */
  1021.     if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
  1022. || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
  1023. || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
  1024. || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI) {
  1025. /* it must be a 32-bit memory reference. Firstly we have
  1026.  * to check that all registers involved are type Exx. */
  1027. if (i!=-1 && i!=R_EAX && i!=R_EBX && i!=R_ECX && i!=R_EDX
  1028.     && i!=R_EBP && i!=R_ESP && i!=R_ESI && i!=R_EDI)
  1029.     return NULL;
  1030. if (b!=-1 && b!=R_EAX && b!=R_EBX && b!=R_ECX && b!=R_EDX
  1031.     && b!=R_EBP && b!=R_ESP && b!=R_ESI && b!=R_EDI)
  1032.     return NULL;
  1033. /* While we're here, ensure the user didn't specify WORD. */
  1034. if (input->addr_size == 16)
  1035.     return NULL;
  1036. /* now reorganise base/index */
  1037. if (s == 1 && b != i && b != -1 && i != -1 &&
  1038.     ((hb==b&&ht==EAH_NOTBASE) || (hb==i&&ht==EAH_MAKEBASE)))
  1039.     t = b, b = i, i = t;   /* swap if hints say so */
  1040. if (b==i)        /* convert EAX+2*EAX to 3*EAX */
  1041.     b = -1, s++;
  1042. if (b==-1 && s==1 && !(hb == i && ht == EAH_NOTBASE))
  1043.     b = i, i = -1;     /* make single reg base, unless hint */
  1044. if (((s==2 && i!=R_ESP && !(input->eaflags & EAF_TIMESTWO)) ||
  1045.      s==3 || s==5 || s==9) && b==-1)
  1046.     b = i, s--;       /* convert 3*EAX to EAX+2*EAX */
  1047. if (s==1 && i==R_ESP)  /* swap ESP into base if scale is 1 */
  1048.     i = b, b = R_ESP;
  1049. if (i==R_ESP || (s!=1 && s!=2 && s!=4 && s!=8 && i!=-1))
  1050.     return NULL;      /* wrong, for various reasons */
  1051. if (i==-1 && b!=R_ESP) {/* no SIB needed */
  1052.     int mod, rm;
  1053.     switch(b) {
  1054.       case R_EAX: rm = 0; break;
  1055.       case R_ECX: rm = 1; break;
  1056.       case R_EDX: rm = 2; break;
  1057.       case R_EBX: rm = 3; break;
  1058.       case R_EBP: rm = 5; break;
  1059.       case R_ESI: rm = 6; break;
  1060.       case R_EDI: rm = 7; break;
  1061.       case -1: rm = 5; break;
  1062.       default:        /* should never happen */
  1063. return NULL;
  1064.     }
  1065.     if (b==-1 || (b!=R_EBP && o==0 &&
  1066.   seg==NO_SEG && !forw_ref &&
  1067.   !(input->eaflags &
  1068.     (EAF_BYTEOFFS|EAF_WORDOFFS))))
  1069.      mod = 0;
  1070.     else if (input->eaflags & EAF_BYTEOFFS ||
  1071.      (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
  1072.       !(input->eaflags & EAF_WORDOFFS))) {
  1073.      mod = 1;
  1074.     } 
  1075.     else
  1076.      mod = 2;
  1077.     output->sib_present = FALSE;
  1078.     output->bytes = (b==-1 || mod==2 ? 4 : mod);
  1079.     output->modrm = (mod<<6) | (rfield<<3) | rm;
  1080. else {        /* we need a SIB */
  1081.     int mod, scale, index, base;
  1082.     switch (b) {
  1083.       case R_EAX: base = 0; break;
  1084.       case R_ECX: base = 1; break;
  1085.       case R_EDX: base = 2; break;
  1086.       case R_EBX: base = 3; break;
  1087.       case R_ESP: base = 4; break;
  1088.       case R_EBP: case -1: base = 5; break;
  1089.       case R_ESI: base = 6; break;
  1090.       case R_EDI: base = 7; break;
  1091.       default:        /* then what the smeg is it? */
  1092. return NULL;  /* panic */
  1093.     }
  1094.     switch (i) {
  1095.       case R_EAX: index = 0; break;
  1096.       case R_ECX: index = 1; break;
  1097.       case R_EDX: index = 2; break;
  1098.       case R_EBX: index = 3; break;
  1099.       case -1: index = 4; break;
  1100.       case R_EBP: index = 5; break;
  1101.       case R_ESI: index = 6; break;
  1102.       case R_EDI: index = 7; break;
  1103.       default:        /* then what the smeg is it? */
  1104. return NULL;  /* panic */
  1105.     }
  1106.     if (i==-1) s = 1;
  1107.     switch (s) {
  1108.       case 1: scale = 0; break;
  1109.       case 2: scale = 1; break;
  1110.       case 4: scale = 2; break;
  1111.       case 8: scale = 3; break;
  1112.       default:        /* then what the smeg is it? */
  1113. return NULL;  /* panic */
  1114.     }
  1115.     if (b==-1 || (b!=R_EBP && o==0 &&
  1116.   seg==NO_SEG && !forw_ref &&
  1117.   !(input->eaflags &
  1118.     (EAF_BYTEOFFS|EAF_WORDOFFS))))
  1119.      mod = 0;
  1120.     else if (input->eaflags & EAF_BYTEOFFS ||
  1121.      (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
  1122.       !(input->eaflags & EAF_WORDOFFS)))
  1123.      mod = 1;
  1124.     else
  1125.      mod = 2;
  1126.     output->sib_present = TRUE;
  1127.     output->bytes = (b==-1 || mod==2 ? 4 : mod);
  1128.     output->modrm = (mod<<6) | (rfield<<3) | 4;
  1129.     output->sib = (scale<<6) | (index<<3) | base;
  1130. }
  1131.     } 
  1132.     else {        /* it's 16-bit */
  1133. int mod, rm;
  1134. /* check all registers are BX, BP, SI or DI */
  1135. if ((b!=-1 && b!=R_BP && b!=R_BX && b!=R_SI && b!=R_DI) ||
  1136.     (i!=-1 && i!=R_BP && i!=R_BX && i!=R_SI && i!=R_DI))
  1137.     return NULL;
  1138. /* ensure the user didn't specify DWORD */
  1139. if (input->addr_size == 32)
  1140.     return NULL;
  1141. if (s!=1 && i!=-1) return NULL;/* no can do, in 16-bit EA */
  1142. if (b==-1 && i!=-1) b ^= i ^= b ^= i;   /* swap them round */
  1143. if ((b==R_SI || b==R_DI) && i!=-1)
  1144.     b ^= i ^= b ^= i; /* have BX/BP as base, SI/DI index */
  1145. if (b==i) return NULL;/* shouldn't ever happen, in theory */
  1146. if (i!=-1 && b!=-1 &&
  1147.     (i==R_BP || i==R_BX || b==R_SI || b==R_DI))
  1148.     return NULL;      /* invalid combinations */
  1149. if (b==-1)        /* pure offset: handled above */
  1150.     return NULL;      /* so if it gets to here, panic! */
  1151. rm = -1;
  1152. if (i!=-1)
  1153.     switch (i*256 + b) {
  1154.       case R_SI*256+R_BX: rm=0; break;
  1155.       case R_DI*256+R_BX: rm=1; break;
  1156.       case R_SI*256+R_BP: rm=2; break;
  1157.       case R_DI*256+R_BP: rm=3; break;
  1158.     }
  1159. else
  1160.     switch (b) {
  1161.       case R_SI: rm=4; break;
  1162.       case R_DI: rm=5; break;
  1163.       case R_BP: rm=6; break;
  1164.       case R_BX: rm=7; break;
  1165.     }
  1166. if (rm==-1)        /* can't happen, in theory */
  1167.     return NULL;      /* so panic if it does */
  1168. if (o==0 && seg==NO_SEG && !forw_ref && rm!=6 &&
  1169.     !(input->eaflags & (EAF_BYTEOFFS|EAF_WORDOFFS)))
  1170.     mod = 0;
  1171. else if (input->eaflags & EAF_BYTEOFFS ||
  1172.  (o>=-128 && o<=127 && seg==NO_SEG && !forw_ref &&
  1173.   !(input->eaflags & EAF_WORDOFFS)))
  1174.     mod = 1;
  1175. else
  1176.     mod = 2;
  1177. output->sib_present = FALSE;  /* no SIB - it's 16-bit */
  1178. output->bytes = mod;  /* bytes of offset needed */
  1179. output->modrm = (mod<<6) | (rfield<<3) | rm;
  1180.     }
  1181. }
  1182.     }
  1183.     output->size = 1 + output->sib_present + output->bytes;
  1184.     return output;
  1185. }
  1186. static int chsize (operand *input, int addrbits) 
  1187. {
  1188.     if (!(MEMORY & ~input->type)) {
  1189. int i=input->indexreg, b=input->basereg;
  1190. if (input->scale==0) i = -1;
  1191. if (i == -1 && b == -1) /* pure offset */
  1192.     return (input->addr_size != 0 && input->addr_size != addrbits);
  1193. if (i==R_EAX || i==R_EBX || i==R_ECX || i==R_EDX
  1194.     || i==R_EBP || i==R_ESP || i==R_ESI || i==R_EDI
  1195.     || b==R_EAX || b==R_EBX || b==R_ECX || b==R_EDX
  1196.     || b==R_EBP || b==R_ESP || b==R_ESI || b==R_EDI)
  1197.     return (addrbits==16);
  1198. else
  1199.     return (addrbits==32);
  1200.     } 
  1201.     else
  1202.      return 0;
  1203. }