distabs.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. static char *sccsid =
  2. "@(#) distabs.c, Ver. 2.1 created 00:00:00 87/09/01";
  3. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  4. * *
  5. * Copyright (C) 1987 G. M. Harding, all rights reserved *
  6. * *
  7. * Permission to copy and redistribute is hereby granted, *
  8. * provided full source code, with all copyright notices, *
  9. * accompanies any redistribution. *
  10. * *
  11. * This file contains the lookup tables and other data *
  12. * structures for the Intel 8088 symbolic disassembler. It *
  13. * also contains a few global routines which facilitate *
  14. * access to the tables, for use primarily by the handler *
  15. * functions. *
  16. * *
  17. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  18. #include "dis.h" /* Disassembler declarations */
  19. struct exec HDR; /* Used to hold header info */
  20. struct nlist symtab[MAXSYM]; /* Array of symbol table info */
  21. struct reloc relo[MAXSYM]; /* Array of relocation info */
  22. int symptr = -1, /* Index into symtab[] */
  23. relptr = -1; /* Index into relo[] */
  24. char *REGS[] = /* Table of register names */
  25. {
  26. "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
  27. "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
  28. "es", "cs", "ss", "ds"
  29. };
  30. char *REGS0[] = /* Mode 0 register name table */
  31. {
  32. "bx_si", "bx_di", "bp_si", "bp_di", "si", "di", "", "bx"
  33. };
  34. char *REGS1[] = /* Mode 1 register name table */
  35. {
  36. "bx_si", "bx_di", "bp_si", "bp_di", "si", "di", "bp", "bx"
  37. };
  38. int symrank[6][6] = /* Symbol type/rank matrix */
  39. {
  40. /* UND ABS TXT DAT BSS COM */
  41. /* UND */ 5, 4, 1, 2, 3, 0,
  42. /* ABS */ 1, 5, 4, 3, 2, 0,
  43. /* TXT */ 4, 1, 5, 3, 2, 0,
  44. /* DAT */ 3, 1, 2, 5, 4, 0,
  45. /* BSS */ 3, 1, 2, 4, 5, 0,
  46. /* COM */ 2, 0, 1, 3, 4, 5
  47. };
  48. /* * * * * * * * * * * * OPCODE DATA * * * * * * * * * * * */
  49. char ADD[] = "\tadd", /* Mnemonics by family */
  50. OR[] = "\tor",
  51. ADC[] = "\tadc",
  52. SBB[] = "\tsbb",
  53. AND[] = "\tand",
  54. SUB[] = "\tsub",
  55. XOR[] = "\txor",
  56. CMP[] = "\tcmp",
  57. NOT[] = "\tnot",
  58. NEG[] = "\tneg",
  59. MUL[] = "\tmul",
  60. DIV[] = "\tdiv",
  61. MOV[] = "\tmov",
  62. ESC[] = "\tesc",
  63. TEST[] = "\ttest",
  64. AMBIG[] = "",
  65. ROL[] = "\trol",
  66. ROR[] = "\tror",
  67. RCL[] = "\trcl",
  68. RCR[] = "\trcr",
  69. SAL[] = "\tsal",
  70. SHR[] = "\tshr",
  71. SHL[] = "\tshl",
  72. SAR[] = "\tsar";
  73. char *OPFAM[] = /* Family lookup table */
  74. {
  75. ADD, OR, ADC, SBB, AND, SUB, XOR, CMP,
  76. NOT, NEG, MUL, DIV, MOV, ESC, TEST, AMBIG,
  77. ROL, ROR, RCL, RCR, SAL, SHR, SHL, SAR
  78. };
  79. struct opcode optab[] = /* Table of opcode data */
  80. {
  81. ADD, aohand, 2, 4, /* 0x00 */
  82. ADD, aohand, 2, 4, /* 0x01 */
  83. ADD, aohand, 2, 4, /* 0x02 */
  84. ADD, aohand, 2, 4, /* 0x03 */
  85. ADD, aohand, 2, 2, /* 0x04 */
  86. ADD, aohand, 3, 3, /* 0x05 */
  87. "\tpush\tes", sbhand, 1, 1, /* 0x06 */
  88. "\tpop\tes", sbhand, 1, 1, /* 0x07 */
  89. OR, aohand, 2, 4, /* 0x08 */
  90. OR, aohand, 2, 4, /* 0x09 */
  91. OR, aohand, 2, 4, /* 0x0a */
  92. OR, aohand, 2, 4, /* 0x0b */
  93. OR, aohand, 2, 2, /* 0x0c */
  94. OR, aohand, 3, 3, /* 0x0d */
  95. "\tpush\tcs", sbhand, 1, 1, /* 0x0e */
  96. "\t.code\t386", sbhand, 1, 1, /* 0x0f */
  97. ADC, aohand, 2, 4, /* 0x10 */
  98. ADC, aohand, 2, 4, /* 0x11 */
  99. ADC, aohand, 2, 4, /* 0x12 */
  100. ADC, aohand, 2, 4, /* 0x13 */
  101. ADC, aohand, 2, 2, /* 0x14 */
  102. ADC, aohand, 3, 3, /* 0x15 */
  103. "\tpush\tss", sbhand, 1, 1, /* 0x16 */
  104. "\tpop\tss", sbhand, 1, 1, /* 0x17 */
  105. SBB, aohand, 2, 4, /* 0x18 */
  106. SBB, aohand, 2, 4, /* 0x19 */
  107. SBB, aohand, 2, 4, /* 0x1a */
  108. SBB, aohand, 2, 4, /* 0x1b */
  109. SBB, aohand, 2, 2, /* 0x1c */
  110. SBB, aohand, 3, 3, /* 0x1d */
  111. "\tpush\tds", sbhand, 1, 1, /* 0x1e */
  112. "\tpop\tds", sbhand, 1, 1, /* 0x1f */
  113. AND, aohand, 2, 4, /* 0x20 */
  114. AND, aohand, 2, 4, /* 0x21 */
  115. AND, aohand, 2, 4, /* 0x22 */
  116. AND, aohand, 2, 4, /* 0x23 */
  117. AND, aohand, 2, 2, /* 0x24 */
  118. AND, aohand, 3, 3, /* 0x25 */
  119. "\tseg\tes", sbhand, 1, 1, /* 0x26 */
  120. "\tdaa", sbhand, 1, 1, /* 0x27 */
  121. SUB, aohand, 2, 4, /* 0x28 */
  122. SUB, aohand, 2, 4, /* 0x29 */
  123. SUB, aohand, 2, 4, /* 0x2a */
  124. SUB, aohand, 2, 4, /* 0x2b */
  125. SUB, aohand, 2, 2, /* 0x2c */
  126. SUB, aohand, 3, 3, /* 0x2d */
  127. "\tseg\tcs", sbhand, 1, 1, /* 0x2e */
  128. "\tdas", sbhand, 1, 1, /* 0x2f */
  129. XOR, aohand, 2, 4, /* 0x30 */
  130. XOR, aohand, 2, 4, /* 0x31 */
  131. XOR, aohand, 2, 4, /* 0x32 */
  132. XOR, aohand, 2, 4, /* 0x33 */
  133. XOR, aohand, 2, 2, /* 0x34 */
  134. XOR, aohand, 3, 3, /* 0x35 */
  135. "\tseg\tss", sbhand, 1, 1, /* 0x36 */
  136. "\taaa", sbhand, 1, 1, /* 0x37 */
  137. CMP, aohand, 2, 4, /* 0x38 */
  138. CMP, aohand, 2, 4, /* 0x39 */
  139. CMP, aohand, 2, 4, /* 0x3a */
  140. CMP, aohand, 2, 4, /* 0x3b */
  141. CMP, aohand, 2, 2, /* 0x3c */
  142. CMP, aohand, 3, 3, /* 0x3d */
  143. "\tseg\tds", sbhand, 1, 1, /* 0x3e */
  144. "\taas", sbhand, 1, 1, /* 0x3f */
  145. "\tinc\tax", sbhand, 1, 1, /* 0x40 */
  146. "\tinc\tcx", sbhand, 1, 1, /* 0x41 */
  147. "\tinc\tdx", sbhand, 1, 1, /* 0x42 */
  148. "\tinc\tbx", sbhand, 1, 1, /* 0x43 */
  149. "\tinc\tsp", sbhand, 1, 1, /* 0x44 */
  150. "\tinc\tbp", sbhand, 1, 1, /* 0x45 */
  151. "\tinc\tsi", sbhand, 1, 1, /* 0x46 */
  152. "\tinc\tdi", sbhand, 1, 1, /* 0x47 */
  153. "\tdec\tax", sbhand, 1, 1, /* 0x48 */
  154. "\tdec\tcx", sbhand, 1, 1, /* 0x49 */
  155. "\tdec\tdx", sbhand, 1, 1, /* 0x4a */
  156. "\tdec\tbx", sbhand, 1, 1, /* 0x4b */
  157. "\tdec\tsp", sbhand, 1, 1, /* 0x4c */
  158. "\tdec\tbp", sbhand, 1, 1, /* 0x4d */
  159. "\tdec\tsi", sbhand, 1, 1, /* 0x4e */
  160. "\tdec\tdi", sbhand, 1, 1, /* 0x4f */
  161. "\tpush\tax", sbhand, 1, 1, /* 0x50 */
  162. "\tpush\tcx", sbhand, 1, 1, /* 0x51 */
  163. "\tpush\tdx", sbhand, 1, 1, /* 0x52 */
  164. "\tpush\tbx", sbhand, 1, 1, /* 0x53 */
  165. "\tpush\tsp", sbhand, 1, 1, /* 0x54 */
  166. "\tpush\tbp", sbhand, 1, 1, /* 0x55 */
  167. "\tpush\tsi", sbhand, 1, 1, /* 0x56 */
  168. "\tpush\tdi", sbhand, 1, 1, /* 0x57 */
  169. "\tpop\tax", sbhand, 1, 1, /* 0x58 */
  170. "\tpop\tcx", sbhand, 1, 1, /* 0x59 */
  171. "\tpop\tdx", sbhand, 1, 1, /* 0x5a */
  172. "\tpop\tbx", sbhand, 1, 1, /* 0x5b */
  173. "\tpop\tsp", sbhand, 1, 1, /* 0x5c */
  174. "\tpop\tbp", sbhand, 1, 1, /* 0x5d */
  175. "\tpop\tsi", sbhand, 1, 1, /* 0x5e */
  176. "\tpop\tdi", sbhand, 1, 1, /* 0x5f */
  177. NULL, dfhand, 0, 0, /* 0x60 */
  178. NULL, dfhand, 0, 0, /* 0x61 */
  179. NULL, dfhand, 0, 0, /* 0x62 */
  180. NULL, dfhand, 0, 0, /* 0x63 */
  181. "\tseg\tfs", sbhand, 1, 1, /* 0x64 */
  182. "\tseg\tgs", sbhand, 1, 1, /* 0x65 */
  183. "\tuse\top32", sbhand, 1, 1, /* 0x66 */
  184. "\tuse\tadr32", sbhand, 1, 1, /* 0x67 */
  185. "\tpush\t", mihand, 3, 3, /* 0x68 */
  186. /* NULL, dfhand, 0, 0, /* 0x68 */
  187. NULL, dfhand, 0, 0, /* 0x69 */
  188. "\tpush\t", mihand, 2, 2, /* 0x6a */
  189. /* NULL, dfhand, 0, 0, /* 0x6a */
  190. NULL, dfhand, 0, 0, /* 0x6b */
  191. NULL, dfhand, 0, 0, /* 0x6c */
  192. NULL, dfhand, 0, 0, /* 0x6d */
  193. NULL, dfhand, 0, 0, /* 0x6e */
  194. NULL, dfhand, 0, 0, /* 0x6f */
  195. "\tjo", sjhand, 2, 2, /* 0x70 */
  196. "\tjno", sjhand, 2, 2, /* 0x71 */
  197. "\tjc", sjhand, 2, 2, /* 0x72 */
  198. "\tjnc", sjhand, 2, 2, /* 0x73 */
  199. "\tjz", sjhand, 2, 2, /* 0x74 */
  200. "\tjnz", sjhand, 2, 2, /* 0x75 */
  201. "\tjna", sjhand, 2, 2, /* 0x76 */
  202. "\tja", sjhand, 2, 2, /* 0x77 */
  203. "\tjs", sjhand, 2, 2, /* 0x78 */
  204. "\tjns", sjhand, 2, 2, /* 0x79 */
  205. "\tjp", sjhand, 2, 2, /* 0x7a */
  206. "\tjnp", sjhand, 2, 2, /* 0x7b */
  207. "\tjl", sjhand, 2, 2, /* 0x7c */
  208. "\tjnl", sjhand, 2, 2, /* 0x7d */
  209. "\tjng", sjhand, 2, 2, /* 0x7e */
  210. "\tjg", sjhand, 2, 2, /* 0x7f */
  211. AMBIG, imhand, 3, 5, /* 0x80 */
  212. AMBIG, imhand, 4, 6, /* 0x81 */
  213. AMBIG, imhand, 3, 5, /* 0x82 */
  214. AMBIG, imhand, 3, 5, /* 0x83 */
  215. TEST, mvhand, 2, 4, /* 0x84 */
  216. TEST, mvhand, 2, 4, /* 0x85 */
  217. "\txchg", mvhand, 2, 4, /* 0x86 */
  218. "\txchg", mvhand, 2, 4, /* 0x87 */
  219. MOV, mvhand, 2, 4, /* 0x88 */
  220. MOV, mvhand, 2, 4, /* 0x89 */
  221. MOV, mvhand, 2, 4, /* 0x8a */
  222. MOV, mvhand, 2, 4, /* 0x8b */
  223. MOV, mshand, 2, 4, /* 0x8c */
  224. "\tlea", mvhand, 2, 4, /* 0x8d */
  225. MOV, mshand, 2, 4, /* 0x8e */
  226. "\tpop", pohand, 2, 4, /* 0x8f */
  227. "\tnop", sbhand, 1, 1, /* 0x90 */
  228. "\txchg\tax,cx", sbhand, 1, 1, /* 0x91 */
  229. "\txchg\tax,dx", sbhand, 1, 1, /* 0x92 */
  230. "\txchg\tax,bx", sbhand, 1, 1, /* 0x93 */
  231. "\txchg\tax,sp", sbhand, 1, 1, /* 0x94 */
  232. "\txchg\tax,bp", sbhand, 1, 1, /* 0x95 */
  233. "\txchg\tax,si", sbhand, 1, 1, /* 0x96 */
  234. "\txchg\tax,di", sbhand, 1, 1, /* 0x97 */
  235. "\tcbw", sbhand, 1, 1, /* 0x98 */
  236. "\tcwd", sbhand, 1, 1, /* 0x99 */
  237. "\tcalli", cihand, 5, 5, /* 0x9a */
  238. "\twait", sbhand, 1, 1, /* 0x9b */
  239. "\tpushf", sbhand, 1, 1, /* 0x9c */
  240. "\tpopf", sbhand, 1, 1, /* 0x9d */
  241. "\tsahf", sbhand, 1, 1, /* 0x9e */
  242. "\tlahf", sbhand, 1, 1, /* 0x9f */
  243. MOV, mqhand, 3, 3, /* 0xa0 */
  244. MOV, mqhand, 3, 3, /* 0xa1 */
  245. MOV, mqhand, 3, 3, /* 0xa2 */
  246. MOV, mqhand, 3, 3, /* 0xa3 */
  247. "\tmovb", sbhand, 1, 1, /* 0xa4 */
  248. "\tmovw", sbhand, 1, 1, /* 0xa5 */
  249. "\tcmpb", sbhand, 1, 1, /* 0xa6 */
  250. "\tcmpw", sbhand, 1, 1, /* 0xa7 */
  251. TEST, tqhand, 2, 2, /* 0xa8 */
  252. TEST, tqhand, 3, 3, /* 0xa9 */
  253. "\tstob", sbhand, 1, 1, /* 0xaa */
  254. "\tstow", sbhand, 1, 1, /* 0xab */
  255. "\tlodb", sbhand, 1, 1, /* 0xac */
  256. "\tlodw", sbhand, 1, 1, /* 0xad */
  257. "\tscab", sbhand, 1, 1, /* 0xae */
  258. "\tscaw", sbhand, 1, 1, /* 0xaf */
  259. "\tmov\tal,", mihand, 2, 2, /* 0xb0 */
  260. "\tmov\tcl,", mihand, 2, 2, /* 0xb1 */
  261. "\tmov\tdl,", mihand, 2, 2, /* 0xb2 */
  262. "\tmov\tbl,", mihand, 2, 2, /* 0xb3 */
  263. "\tmov\tah,", mihand, 2, 2, /* 0xb4 */
  264. "\tmov\tch,", mihand, 2, 2, /* 0xb5 */
  265. "\tmov\tdh,", mihand, 2, 2, /* 0xb6 */
  266. "\tmov\tbh,", mihand, 2, 2, /* 0xb7 */
  267. "\tmov\tax,", mihand, 3, 3, /* 0xb8 */
  268. "\tmov\tcx,", mihand, 3, 3, /* 0xb9 */
  269. "\tmov\tdx,", mihand, 3, 3, /* 0xba */
  270. "\tmov\tbx,", mihand, 3, 3, /* 0xbb */
  271. "\tmov\tsp,", mihand, 3, 3, /* 0xbc */
  272. "\tmov\tbp,", mihand, 3, 3, /* 0xbd */
  273. "\tmov\tsi,", mihand, 3, 3, /* 0xbe */
  274. "\tmov\tdi,", mihand, 3, 3, /* 0xbf */
  275. NULL, dfhand, 0, 0, /* 0xc0 */
  276. NULL, dfhand, 0, 0, /* 0xc1 */
  277. "\tret", rehand, 3, 3, /* 0xc2 */
  278. "\tret", sbhand, 1, 1, /* 0xc3 */
  279. "\tles", mvhand, 2, 4, /* 0xc4 */
  280. "\tlds", mvhand, 2, 4, /* 0xc5 */
  281. MOV, mmhand, 3, 5, /* 0xc6 */
  282. MOV, mmhand, 4, 6, /* 0xc7 */
  283. NULL, dfhand, 0, 0, /* 0xc8 */
  284. NULL, dfhand, 0, 0, /* 0xc9 */
  285. "\treti", rehand, 3, 3, /* 0xca */
  286. "\treti", sbhand, 1, 1, /* 0xcb */
  287. "\tint", sbhand, 1, 1, /* 0xcc */
  288. "\tint", inhand, 2, 2, /* 0xcd */
  289. "\tinto", sbhand, 1, 1, /* 0xce */
  290. "\tiret", sbhand, 1, 1, /* 0xcf */
  291. AMBIG, srhand, 2, 4, /* 0xd0 */
  292. AMBIG, srhand, 2, 4, /* 0xd1 */
  293. AMBIG, srhand, 2, 4, /* 0xd2 */
  294. AMBIG, srhand, 2, 4, /* 0xd3 */
  295. "\taam", aahand, 2, 2, /* 0xd4 */
  296. "\taad", aahand, 2, 2, /* 0xd5 */
  297. NULL, dfhand, 0, 0, /* 0xd6 */
  298. "\txlat", sbhand, 1, 1, /* 0xd7 */
  299. ESC, eshand, 2, 2, /* 0xd8 */
  300. ESC, eshand, 2, 2, /* 0xd9 */
  301. ESC, eshand, 2, 2, /* 0xda */
  302. ESC, eshand, 2, 2, /* 0xdb */
  303. ESC, eshand, 2, 2, /* 0xdc */
  304. ESC, eshand, 2, 2, /* 0xdd */
  305. ESC, eshand, 2, 2, /* 0xde */
  306. ESC, eshand, 2, 2, /* 0xdf */
  307. "\tloopne", sjhand, 2, 2, /* 0xe0 */
  308. "\tloope", sjhand, 2, 2, /* 0xe1 */
  309. "\tloop", sjhand, 2, 2, /* 0xe2 */
  310. "\tjcxz", sjhand, 2, 2, /* 0xe3 */
  311. "\tin", iohand, 2, 2, /* 0xe4 */
  312. "\tinw", iohand, 2, 2, /* 0xe5 */
  313. "\tout", iohand, 2, 2, /* 0xe6 */
  314. "\toutw", iohand, 2, 2, /* 0xe7 */
  315. "\tcall", ljhand, 3, 3, /* 0xe8 */
  316. "\tjmp", ljhand, 3, 3, /* 0xe9 */
  317. "\tjmpi", cihand, 5, 5, /* 0xea */
  318. "\tj", sjhand, 2, 2, /* 0xeb */
  319. "\tin", sbhand, 1, 1, /* 0xec */
  320. "\tinw", sbhand, 1, 1, /* 0xed */
  321. "\tout", sbhand, 1, 1, /* 0xee */
  322. "\toutw", sbhand, 1, 1, /* 0xef */
  323. "\tlock", sbhand, 1, 1, /* 0xf0 */
  324. NULL, dfhand, 0, 0, /* 0xf1 */
  325. "\trepnz", sbhand, 1, 1, /* 0xf2 */
  326. "\trepz", sbhand, 1, 1, /* 0xf3 */
  327. "\thlt", sbhand, 1, 1, /* 0xf4 */
  328. "\tcmc", sbhand, 1, 1, /* 0xf5 */
  329. AMBIG, mahand, 2, 5, /* 0xf6 */
  330. AMBIG, mahand, 2, 6, /* 0xf7 */
  331. "\tclc", sbhand, 1, 1, /* 0xf8 */
  332. "\tstc", sbhand, 1, 1, /* 0xf9 */
  333. "\tcli", sbhand, 1, 1, /* 0xfa */
  334. "\tsti", sbhand, 1, 1, /* 0xfb */
  335. "\tcld", sbhand, 1, 1, /* 0xfc */
  336. "\tstd", sbhand, 1, 1, /* 0xfd */
  337. AMBIG, mjhand, 2, 4, /* 0xfe */
  338. AMBIG, mjhand, 2, 4 /* 0xff */
  339. };
  340. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  341. * *
  342. * This simple routine returns the name field of a symbol *
  343. * table entry as a printable string. *
  344. * *
  345. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  346. char *
  347. getnam(k)
  348. register int k;
  349. {/* * * * * * * * * * START OF getnam() * * * * * * * * * */
  350. register int j;
  351. static char a[sizeof(symtab->n_name)+1];
  352. for (j = 0; j < sizeof(symtab[k].n_name); ++j)
  353. if ( ! symtab[k].n_name[j] )
  354. break;
  355. else
  356. a[j] = symtab[k].n_name[j];
  357. a[j] = '\0';
  358. return (a);
  359. }/* * * * * * * * * * * END OF getnam() * * * * * * * * * * */
  360. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  361. * *
  362. * This function is responsible for mucking through the *
  363. * relocation table in search of externally referenced *
  364. * symbols to be output as operands. It accepts two long *
  365. * arguments: the code-segment location at which an extern *
  366. * reference is expected, and the offset value which is *
  367. * embedded in the object code and used at link time to *
  368. * bias the external value. In the most typical case, the *
  369. * function will be called by lookup(), which always makes *
  370. * a check for external names before searching the symbol *
  371. * table proper. However, it may also be called directly *
  372. * by any function (such as the move-immediate handler) *
  373. * which wants to make an independent check for externals. *
  374. * The caller is expected to supply, as the third argument *
  375. * to the function, a pointer to a character buffer large *
  376. * enough to hold any possible output string. Lookext() *
  377. * will fill this buffer and return a logical TRUE if it *
  378. * finds an extern reference; otherwise, it will return a *
  379. * logical FALSE, leaving the buffer undisturbed. *
  380. * *
  381. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  382. int
  383. lookext(off,loc,buf)
  384. long off, loc;
  385. char *buf;
  386. {/* * * * * * * * * * START OF lookext() * * * * * * * * * */
  387. register int k;
  388. char c[32];
  389. if ((loc != -1L) && (relptr >= 0))
  390. for (k = 0; k <= relptr; ++k)
  391. if ((relo[k].r_vaddr == loc)
  392. && (relo[k].r_symndx < S_BSS))
  393. {
  394. strcpy(buf,getnam(relo[k].r_symndx));
  395. if (off)
  396. {
  397. if (off < 0)
  398. sprintf(c,"%ld",off);
  399. else
  400. sprintf(c,"+%ld",off);
  401. strcat(buf,c);
  402. }
  403. return (1);
  404. }
  405. return (0);
  406. }/* * * * * * * * * * END OF lookext() * * * * * * * * * */
  407. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  408. * *
  409. * This function finds an entry in the symbol table by *
  410. * value. Its input is a (long) machine address, and its *
  411. * output is a pointer to a string containing the corre- *
  412. * sponding symbolic name. The function first searches the *
  413. * relocation table for a possible external reference; if *
  414. * none is found, a linear search of the symbol table is *
  415. * undertaken. If no matching symbol has been found at the *
  416. * end of these searches, the function returns a pointer *
  417. * to a string containing the ASCII equivalent of the ad- *
  418. * dress which was to be located, so that, regardless of *
  419. * the success of the search, the function's return value *
  420. * is suitable for use as a memory-reference operand. The *
  421. * caller specifies the type of symbol to be found (text, *
  422. * data, bss, undefined, absolute, or common) by means of *
  423. * the function's second parameter. The third parameter *
  424. * specifies the format to be used in the event of a nu- *
  425. * meric output: zero for absolute format, one for short *
  426. * relative format, two for long relative format. The *
  427. * fourth parameter is the address which would appear in *
  428. * the relocation table for the reference in question, or *
  429. * -1 if the relocation table is not to be searched. The *
  430. * function attempts to apply a certain amount of intelli- *
  431. * gence in its selection of symbols, so it is possible *
  432. * that, in the absence of a type match, a symbol of the *
  433. * correct value but different type will be returned. *
  434. * *
  435. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  436. char *
  437. lookup(addr,type,kind,ext)
  438. long addr; /* Machine address to be located */
  439. int type, /* Type of symbol to be matched */
  440. kind; /* Addressing output mode to use */
  441. long ext; /* Value for extern ref, if any */
  442. {/* * * * * * * * * * START OF lookup() * * * * * * * * * */
  443. register int j, k;
  444. static char b[80];
  445. struct
  446. {
  447. int i;
  448. int t;
  449. }
  450. best;
  451. if (lookext(addr,ext,b))
  452. return (b);
  453. if (segflg)
  454. if (segflg & 1)
  455. type = N_TEXT;
  456. else
  457. type = N_DATA;
  458. for (k = 0, best.i = -1; k <= symptr; ++k)
  459. if (symtab[k].n_value == addr)
  460. if ((j = symtab[k].n_sclass & N_SECT) == type)
  461. {
  462. best.t = j;
  463. best.i = k;
  464. break;
  465. }
  466. else if (segflg || (HDR.a_flags & A_SEP))
  467. continue;
  468. else if (best.i < 0)
  469. best.t = j, best.i = k;
  470. else if (symrank[type][j] > symrank[type][best.t])
  471. best.t = j, best.i = k;
  472. if (best.i >= 0)
  473. return (getnam(best.i));
  474. if (kind == LOOK_ABS)
  475. sprintf(b,"$%04lx",addr);
  476. else
  477. {
  478. long x = addr - (PC - kind);
  479. if (x < 0)
  480. sprintf(b,".%ld",x);
  481. else
  482. sprintf(b,".+%ld",x);
  483. }
  484. return (b);
  485. }/* * * * * * * * * * * END OF lookup() * * * * * * * * * * */
  486. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  487. * *
  488. * This function translates an 8088 addressing mode byte *
  489. * to an equivalent assembler string, returning a pointer *
  490. * thereto. If necessary, it performs successive inputs *
  491. * of bytes from the object file in order to obtain offset *
  492. * data, adjusting PC accordingly. (The addressing mode *
  493. * byte appears in several 8088 opcodes; it is used to *
  494. * specify source and destination operand locations.) The *
  495. * third argument to the function is zero if the standard *
  496. * registers are to be used, or eight if the segment reg- *
  497. * isters are to be used; these constants are defined sym- *
  498. * bolically in dis.h. NOTE: The mtrans() function must *
  499. * NEVER be called except immediately after fetching the *
  500. * mode byte. If any additional object bytes are fetched *
  501. * after the fetch of the mode byte, mtrans() will not *
  502. * produce correct output! *
  503. * *
  504. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  505. #undef FRV
  506. #define FRV ""
  507. char *
  508. mtrans(c,m,type)
  509. register int c; /* Primary instruction byte */
  510. register int m; /* Addressing mode byte */
  511. int type; /* Type code: standard or seg */
  512. {/* * * * * * * * * * START OF mtrans() * * * * * * * * * */
  513. unsigned long pc;
  514. int offset, oflag, dir, w, mod, reg, rm;
  515. static char a[100];
  516. static char b[30];
  517. offset = 0;
  518. dir = c & 2;
  519. w = c & 1;
  520. mod = (m & 0xc0) >> 6;
  521. reg = (m & 0x38) >> 3;
  522. rm = m & 7;
  523. pc = PC + 1;
  524. if (type)
  525. w = 1;
  526. if ((oflag = mod) > 2)
  527. oflag = 0;
  528. if (oflag)
  529. {
  530. int j, k;
  531. if (oflag == 2)
  532. {
  533. FETCH(j);
  534. FETCH(k);
  535. offset = (k << 8) | j;
  536. }
  537. else
  538. {
  539. FETCH(j);
  540. if (j & 0x80)
  541. k = 0xff00;
  542. else
  543. k = 0;
  544. offset = k | j;
  545. }
  546. }
  547. if (dir)
  548. {
  549. strcpy(a,REGS[type + ((w << 3) | reg)]);
  550. strcat(a,",");
  551. switch (mod)
  552. {
  553. case 0 :
  554. if (rm == 6)
  555. {
  556. int j, k;
  557. FETCH(j);
  558. FETCH(k);
  559. offset = (k << 8) | j;
  560. strcat(a,
  561. lookup((long)(offset),N_DATA,LOOK_ABS,pc));
  562. }
  563. else
  564. {
  565. sprintf(b,"(%s)",REGS0[rm]);
  566. strcat(a,b);
  567. }
  568. break;
  569. case 1 :
  570. case 2 :
  571. if (mod == 1)
  572. strcat(a,"*");
  573. else
  574. strcat(a,"#");
  575. sprintf(b,"%d(", (short)offset);
  576. strcat(a,b);
  577. strcat(a,REGS1[rm]);
  578. strcat(a,")");
  579. break;
  580. case 3 :
  581. strcat(a,REGS[(w << 3) | rm]);
  582. break;
  583. }
  584. }
  585. else
  586. {
  587. switch (mod)
  588. {
  589. case 0 :
  590. if (rm == 6)
  591. {
  592. int j, k;
  593. FETCH(j);
  594. FETCH(k);
  595. offset = (k << 8) | j;
  596. strcpy(a,
  597. lookup((long)(offset),N_DATA,LOOK_ABS,pc));
  598. }
  599. else
  600. {
  601. sprintf(b,"(%s)",REGS0[rm]);
  602. strcpy(a,b);
  603. }
  604. break;
  605. case 1 :
  606. case 2 :
  607. if (mod == 1)
  608. strcpy(a,"*");
  609. else
  610. strcpy(a,"#");
  611. sprintf(b,"%d(", (short)offset);
  612. strcat(a,b);
  613. strcat(a,REGS1[rm]);
  614. strcat(a,")");
  615. break;
  616. case 3 :
  617. strcpy(a,REGS[(w << 3) | rm]);
  618. break;
  619. }
  620. strcat(a,",");
  621. strcat(a,REGS[type + ((w << 3) | reg)]);
  622. }
  623. return (a);
  624. }/* * * * * * * * * * * END OF mtrans() * * * * * * * * * * */
  625. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  626. * *
  627. * This simple routine truncates a string returned by the *
  628. * mtrans() function, removing its source operand. This is *
  629. * useful in handlers which ignore the "reg" field of the *
  630. * mode byte. *
  631. * *
  632. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  633. void
  634. mtrunc(a)
  635. register char *a; /* Ptr. to string to truncate */
  636. {/* * * * * * * * * * START OF mtrunc() * * * * * * * * * */
  637. register int k;
  638. for (k = strlen(a) - 1; k >= 0; --k)
  639. if (a[k] == ',')
  640. {
  641. a[k] = '\0';
  642. break;
  643. }
  644. }/* * * * * * * * * * * END OF mtrunc() * * * * * * * * * * */