ag386int.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. {
  2. $Id$
  3. Copyright (c) 1996,97 by Florian Klaempfl
  4. This unit implements an asmoutput class for Intel syntax with Intel i386+
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit ag386int;
  19. interface
  20. uses aasm,assemble;
  21. type
  22. pi386intasmlist=^ti386intasmlist;
  23. ti386intasmlist = object(tasmlist)
  24. procedure WriteTree(p:paasmoutput);virtual;
  25. procedure WriteAsmList;virtual;
  26. end;
  27. implementation
  28. uses
  29. dos,globals,systems,cobjects,i386,
  30. strings,files,verbose
  31. {$ifdef GDB}
  32. ,gdb
  33. {$endif GDB}
  34. ;
  35. const
  36. line_length = 70;
  37. extstr : array[EXT_NEAR..EXT_ABS] of String[8] =
  38. ('NEAR','FAR','PROC','BYTE','WORD','DWORD',
  39. 'CODEPTR','DATAPTR','FWORD','PWORD','QWORD','TBYTE','ABS');
  40. function getreferencestring(const ref : treference) : string;
  41. var
  42. s : string;
  43. first : boolean;
  44. begin
  45. if ref.isintvalue then
  46. s:= tostr(ref.offset)
  47. else
  48. with ref do
  49. begin
  50. first:=true;
  51. if ref.segment<>R_DEFAULT_SEG then
  52. begin
  53. if current_module^.output_format in [of_nasm,of_obj] then
  54. s:='['+int_reg2str[segment]+':'
  55. else
  56. s:=int_reg2str[segment]+':[';
  57. end
  58. else
  59. s:='[';
  60. if assigned(symbol) then
  61. begin
  62. s:=s+symbol^;
  63. first:=false;
  64. end;
  65. if (base<>R_NO) then
  66. begin
  67. if not(first) then
  68. s:=s+'+'
  69. else
  70. first:=false;
  71. s:=s+int_reg2str[base];
  72. end;
  73. if (index<>R_NO) then
  74. begin
  75. if not(first) then
  76. s:=s+'+'
  77. else
  78. first:=false;
  79. s:=s+int_reg2str[index];
  80. if scalefactor<>0 then
  81. s:=s+'*'+tostr(scalefactor);
  82. end;
  83. if offset<0 then
  84. s:=s+tostr(offset)
  85. else if (offset>0) then
  86. s:=s+'+'+tostr(offset);
  87. s:=s+']';
  88. end;
  89. getreferencestring:=s;
  90. end;
  91. function getopstr(t : byte;o : pointer;s : topsize; _operator: tasmop;dest : boolean) : string;
  92. var
  93. hs : string;
  94. begin
  95. case t of
  96. top_reg : { a floating point register can be only a register operand }
  97. if current_module^.output_format in [of_nasm,of_obj] then
  98. getopstr:=int_nasmreg2str[tregister(o)]
  99. else
  100. getopstr:=int_reg2str[tregister(o)];
  101. top_const,
  102. top_ref : begin
  103. if t=top_const then
  104. hs := tostr(longint(o))
  105. else
  106. hs:=getreferencestring(preference(o)^);
  107. if current_module^.output_format in [of_nasm,of_obj] then
  108. if (_operator = A_LEA) or (_operator = A_LGS)
  109. or (_operator = A_LSS) or (_operator = A_LFS)
  110. or (_operator = A_LES) or (_operator = A_LDS)
  111. or (_operator = A_SHR) or (_operator = A_SHL)
  112. or (_operator = A_SAR) or (_operator = A_SAL)
  113. or (_operator = A_OUT) or (_operator = A_IN) then
  114. begin
  115. end
  116. else
  117. case s of
  118. S_B : hs:='byte '+hs;
  119. S_W : hs:='word '+hs;
  120. S_L : hs:='dword '+hs;
  121. S_IS : hs:='word '+hs;
  122. S_IL : hs:='dword '+hs;
  123. S_IQ : hs:='qword '+hs;
  124. S_FS : hs:='dword '+hs;
  125. S_FL : hs:='qword '+hs;
  126. S_FX : hs:='tword '+hs;
  127. S_BW : if dest then
  128. hs:='word '+hs
  129. else
  130. hs:='byte '+hs;
  131. S_BL : if dest then
  132. hs:='dword '+hs
  133. else
  134. hs:='byte '+hs;
  135. S_WL : if dest then
  136. hs:='dword '+hs
  137. else
  138. hs:='word '+hs;
  139. end
  140. else
  141. Begin
  142. { can possibly give a range check error under tp }
  143. { if using in... }
  144. if ((_operator <> A_LGS) and (_operator <> A_LSS) and
  145. (_operator <> A_LFS) and (_operator <> A_LDS) and
  146. (_operator <> A_LES)) then
  147. Begin
  148. case s of
  149. S_B : hs:='byte ptr '+hs;
  150. S_W : hs:='word ptr '+hs;
  151. S_L : hs:='dword ptr '+hs;
  152. S_IS : hs:='word ptr '+hs;
  153. S_IL : hs:='dword ptr '+hs;
  154. S_IQ : hs:='qword ptr '+hs;
  155. S_FS : hs:='dword ptr '+hs;
  156. S_FL : hs:='qword ptr '+hs;
  157. S_FX : hs:='tbyte ptr '+hs;
  158. S_BW : if dest then
  159. hs:='word ptr '+hs
  160. else
  161. hs:='byte ptr '+hs;
  162. S_BL : if dest then
  163. hs:='dword ptr '+hs
  164. else
  165. hs:='byte ptr '+hs;
  166. S_WL : if dest then
  167. hs:='dword ptr '+hs
  168. else
  169. hs:='word ptr '+hs;
  170. end;
  171. end;
  172. end;
  173. getopstr:=hs;
  174. end;
  175. top_symbol : begin
  176. hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
  177. move(pchar(pcsymbol(o)^.symbol)^,hs[1],byte(hs[0]));
  178. if current_module^.output_format=of_masm then
  179. hs:='offset '+hs
  180. else
  181. hs:='dword '+hs;
  182. if pcsymbol(o)^.offset>0 then
  183. hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  184. else if pcsymbol(o)^.offset<0 then
  185. hs:=hs+tostr(pcsymbol(o)^.offset);
  186. getopstr:=hs;
  187. end;
  188. else internalerror(10001);
  189. end;
  190. end;
  191. function getopstr_jmp(t : byte;o : pointer) : string;
  192. var
  193. hs : string;
  194. begin
  195. case t of
  196. top_reg : getopstr_jmp:=int_reg2str[tregister(o)];
  197. top_ref : getopstr_jmp:=getreferencestring(preference(o)^);
  198. top_const : getopstr_jmp:=tostr(longint(o));
  199. top_symbol : begin
  200. hs[0]:=chr(strlen(pchar(pcsymbol(o)^.symbol)));
  201. move(pchar(pcsymbol(o)^.symbol)^,hs[1],byte(hs[0]));
  202. if pcsymbol(o)^.offset>0 then
  203. hs:=hs+'+'+tostr(pcsymbol(o)^.offset)
  204. else if pcsymbol(o)^.offset<0 then
  205. hs:=hs+tostr(pcsymbol(o)^.offset);
  206. getopstr_jmp:=hs;
  207. end;
  208. else internalerror(10001);
  209. end;
  210. end;
  211. {****************************************************************************
  212. TI386INTASMLIST
  213. ****************************************************************************}
  214. var
  215. LastSec : tsection;
  216. const
  217. ait_const2str:array[ait_const_32bit..ait_const_8bit] of string[8]=
  218. (#9'DD'#9,'',#9'DW'#9,#9'DB'#9);
  219. ait_section2nasmstr : array[tsection] of string[6]=
  220. ('','.text','.data','.bss','.idata');
  221. ait_section2masmstr : array[tsection] of string[6]=
  222. ('','CODE','DATA','BSS','');
  223. Function PadTabs(p:pchar;addch:char):string;
  224. var
  225. s : string;
  226. i : longint;
  227. begin
  228. i:=strlen(p);
  229. if addch<>#0 then
  230. begin
  231. inc(i);
  232. s:=StrPas(p)+addch;
  233. end
  234. else
  235. s:=StrPas(p);
  236. if i<8 then
  237. PadTabs:=s+#9#9
  238. else
  239. PadTabs:=s+#9;
  240. end;
  241. procedure ti386intasmlist.WriteTree(p:paasmoutput);
  242. type
  243. twowords=record
  244. word1,word2:word;
  245. end;
  246. var
  247. s,
  248. prefix,
  249. suffix : string;
  250. hp : pai;
  251. counter,
  252. lines,
  253. i,j,l : longint;
  254. consttyp : tait;
  255. found,
  256. quoted : boolean;
  257. begin
  258. if not assigned(p) then
  259. exit;
  260. hp:=pai(p^.first);
  261. while assigned(hp) do
  262. begin
  263. case hp^.typ of
  264. ait_comment : Begin
  265. AsmWrite(target_asm.comment);
  266. AsmWritePChar(pai_asm_comment(hp)^.str);
  267. AsmLn;
  268. End;
  269. ait_section : begin
  270. if current_module^.output_format in [of_nasm,of_obj] then
  271. AsmWriteLn('SECTION '+ait_section2nasmstr[pai_section(hp)^.sec])
  272. else
  273. begin
  274. if LastSec<>sec_none then
  275. AsmWriteLn('_'+ait_section2masmstr[LastSec]+#9#9'ENDS');
  276. AsmWriteLn('_'+ait_section2masmstr[pai_section(hp)^.sec]+'DATA'#9#9+
  277. 'SEGMENT'#9'PARA PUBLIC USE32 '''+ait_section2masmstr[pai_section(hp)^.sec]+'''');
  278. end;
  279. LastSec:=pai_section(hp)^.sec;
  280. end;
  281. ait_align : begin
  282. { align not supported at all with nasm v095 }
  283. { align with specific value not supported by }
  284. { turbo assembler. }
  285. { CAUSES PROBLEMS WITH THE SEGMENT DEFINITION }
  286. { SEGMENT DEFINITION SHOULD MATCH TYPE OF ALIGN }
  287. { HERE UNDER TASM! }
  288. { if current_module^.output_format<>of_nasm then }
  289. AsmWriteLn(#9'ALIGN '+tostr(pai_align(hp)^.aligntype));
  290. end;
  291. ait_external : begin
  292. if current_module^.output_format in [of_nasm,of_obj] then
  293. AsmWriteLn('EXTERN '+StrPas(pai_external(hp)^.name))
  294. else
  295. AsmWriteLn(#9#9'EXTRN'#9+StrPas(pai_external(hp)^.name)+
  296. ' :'+extstr[pai_external(hp)^.exttyp]);
  297. end;
  298. ait_datablock : begin
  299. if current_module^.output_format in [of_nasm,of_obj] then
  300. begin
  301. if pai_datablock(hp)^.is_global then
  302. AsmWriteLn('GLOBAL '+StrPas(pai_datablock(hp)^.name));
  303. AsmWriteLn(PadTabs(pai_datablock(hp)^.name,':')+'RESB'#9+tostr(pai_datablock(hp)^.size));
  304. end
  305. else
  306. begin
  307. if pai_datablock(hp)^.is_global then
  308. AsmWriteLn(#9#9'PUBLIC'#9+StrPas(pai_datablock(hp)^.name));
  309. AsmWriteLn(PadTabs(pai_datablock(hp)^.name,#0)+'DB'#9+tostr(pai_datablock(hp)^.size)+' DUP(?)');
  310. end;
  311. end;
  312. ait_const_32bit,
  313. ait_const_8bit,
  314. ait_const_16bit : begin
  315. AsmWrite(ait_const2str[hp^.typ]+tostr(pai_const(hp)^.value));
  316. consttyp:=hp^.typ;
  317. l:=0;
  318. repeat
  319. found:=(not (Pai(hp^.next)=nil)) and (Pai(hp^.next)^.typ=consttyp);
  320. if found then
  321. begin
  322. hp:=Pai(hp^.next);
  323. s:=','+tostr(pai_const(hp)^.value);
  324. AsmWrite(s);
  325. inc(l,length(s));
  326. end;
  327. until (not found) or (l>line_length);
  328. AsmLn;
  329. end;
  330. ait_const_symbol : begin
  331. if current_module^.output_format<>of_nasm then
  332. AsmWrite(#9#9+'DD '#9'offset ')
  333. else
  334. AsmWrite(#9#9+'DD '#9);
  335. AsmWriteLn(StrPas(pchar(pai_const(hp)^.value)));
  336. end;
  337. ait_real_32bit : AsmWriteLn(#9#9'DD'#9+double2str(pai_single(hp)^.value));
  338. ait_real_64bit : AsmWriteLn(#9#9'DQ'#9+double2str(pai_double(hp)^.value));
  339. ait_real_extended : begin
  340. { nasm v095 does not like DT with real constants }
  341. { therefore write as double. }
  342. { other possible solution: decode directly to hex}
  343. { value. }
  344. if current_module^.output_format<>of_nasm then
  345. AsmWriteLn(#9#9'DT'#9+double2str(pai_extended(hp)^.value))
  346. else
  347. begin
  348. {$ifdef EXTDEBUG}
  349. AsmLn;
  350. AsmWriteLn('; NASM bug work around for extended real');
  351. {$endif}
  352. AsmWriteLn(#9#9'DD'#9+double2str(pai_extended(hp)^.value))
  353. end;
  354. end;
  355. ait_comp : AsmWriteLn(#9#9'DQ'#9+comp2str(pai_extended(hp)^.value));
  356. ait_string : begin
  357. counter := 0;
  358. lines := pai_string(hp)^.len div line_length;
  359. { separate lines in different parts }
  360. if pai_string(hp)^.len > 0 then
  361. Begin
  362. for j := 0 to lines-1 do
  363. begin
  364. AsmWrite(#9#9'DB'#9);
  365. quoted:=false;
  366. for i:=counter to counter+line_length do
  367. begin
  368. { it is an ascii character. }
  369. if (ord(pai_string(hp)^.str[i])>31) and
  370. (ord(pai_string(hp)^.str[i])<128) and
  371. (pai_string(hp)^.str[i]<>'"') then
  372. begin
  373. if not(quoted) then
  374. begin
  375. if i>counter then
  376. AsmWrite(',');
  377. AsmWrite('"');
  378. end;
  379. AsmWrite(pai_string(hp)^.str[i]);
  380. quoted:=true;
  381. end { if > 31 and < 128 and ord('"') }
  382. else
  383. begin
  384. if quoted then
  385. AsmWrite('"');
  386. if i>counter then
  387. AsmWrite(',');
  388. quoted:=false;
  389. AsmWrite(tostr(ord(pai_string(hp)^.str[i])));
  390. end;
  391. end; { end for i:=0 to... }
  392. if quoted then AsmWrite('"');
  393. AsmWrite(target_os.newline);
  394. counter := counter+line_length;
  395. end; { end for j:=0 ... }
  396. { do last line of lines }
  397. AsmWrite(#9#9'DB'#9);
  398. quoted:=false;
  399. for i:=counter to pai_string(hp)^.len-1 do
  400. begin
  401. { it is an ascii character. }
  402. if (ord(pai_string(hp)^.str[i])>31) and
  403. (ord(pai_string(hp)^.str[i])<128) and
  404. (pai_string(hp)^.str[i]<>'"') then
  405. begin
  406. if not(quoted) then
  407. begin
  408. if i>counter then
  409. AsmWrite(',');
  410. AsmWrite('"');
  411. end;
  412. AsmWrite(pai_string(hp)^.str[i]);
  413. quoted:=true;
  414. end { if > 31 and < 128 and " }
  415. else
  416. begin
  417. if quoted then
  418. AsmWrite('"');
  419. if i>counter then
  420. AsmWrite(',');
  421. quoted:=false;
  422. AsmWrite(tostr(ord(pai_string(hp)^.str[i])));
  423. end;
  424. end; { end for i:=0 to... }
  425. if quoted then
  426. AsmWrite('"');
  427. end;
  428. AsmLn;
  429. end;
  430. ait_label : begin
  431. AsmWrite(lab2str(pai_label(hp)^.l));
  432. if (current_module^.output_format in [of_obj,of_nasm]) or
  433. (assigned(hp^.next) and not(pai(hp^.next)^.typ in
  434. [ait_const_32bit,ait_const_16bit,ait_const_8bit,ait_const_symbol,
  435. ait_real_32bit,ait_real_64bit,ait_real_extended,ait_string])) then
  436. AsmWriteLn(':');
  437. end;
  438. ait_direct : begin
  439. AsmWritePChar(pai_direct(hp)^.str);
  440. AsmLn;
  441. end;
  442. ait_labeled_instruction :
  443. begin
  444. if (current_module^.output_format in [of_nasm,of_obj]) and
  445. not (pai_labeled(hp)^._operator in [A_JMP,A_LOOP,A_LOOPZ,A_LOOPE,
  446. A_LOOPNZ,A_LOOPNE,A_JCXZ,A_JECXZ]) then
  447. AsmWriteLn(#9#9+int_op2str[pai_labeled(hp)^._operator]+#9+'near '+lab2str(pai_labeled(hp)^.lab))
  448. else
  449. AsmWriteLn(#9#9+int_op2str[pai_labeled(hp)^._operator]+#9+lab2str(pai_labeled(hp)^.lab));
  450. end;
  451. ait_symbol : begin
  452. if pai_symbol(hp)^.is_global then
  453. begin
  454. if current_module^.output_format in [of_nasm,of_obj] then
  455. AsmWriteLn('GLOBAL '+StrPas(pai_symbol(hp)^.name))
  456. else
  457. AsmWriteLn(#9#9'PUBLIC'#9+StrPas(pai_symbol(hp)^.name));
  458. end;
  459. AsmWritePChar(pai_symbol(hp)^.name);
  460. if assigned(hp^.next) and not(pai(hp^.next)^.typ in
  461. [ait_const_32bit,ait_const_16bit,ait_const_8bit,ait_const_symbol,
  462. ait_real_64bit,ait_string]) then
  463. AsmWriteLn(':')
  464. end;
  465. ait_instruction : begin
  466. suffix:='';
  467. prefix:= '';
  468. { added prefix instructions, must be on same line as opcode }
  469. if (pai386(hp)^.op1t = top_none) and
  470. ((pai386(hp)^._operator = A_REP) or
  471. (pai386(hp)^._operator = A_LOCK) or
  472. (pai386(hp)^._operator = A_REPE) or
  473. (pai386(hp)^._operator = A_REPNE)) then
  474. Begin
  475. prefix:=int_op2str[pai386(hp)^._operator]+#9;
  476. hp:=Pai(hp^.next);
  477. { this is theorically impossible... }
  478. if hp=nil then
  479. begin
  480. s:=#9#9+prefix;
  481. AsmWriteLn(s);
  482. break;
  483. end;
  484. { nasm prefers prefix on a line alone }
  485. if (current_module^.output_format in [of_nasm,of_obj]) then
  486. begin
  487. AsmWriteln(#9#9+prefix);
  488. prefix:='';
  489. end;
  490. end
  491. else
  492. prefix:= '';
  493. { A_FNSTS need the w as suffix at least for nasm}
  494. if (current_module^.output_format in [of_nasm,of_obj]) then
  495. if (pai386(hp)^._operator = A_FNSTS) then
  496. pai386(hp)^._operator:=A_FNSTSW
  497. else if (pai386(hp)^._operator = A_FSTS) then
  498. pai386(hp)^._operator:=A_FSTSW;
  499. if pai386(hp)^.op1t<>top_none then
  500. begin
  501. if pai386(hp)^._operator in [A_CALL] then
  502. begin
  503. if output_format=of_nasm then
  504. s:=getopstr_jmp(pai386(hp)^.op1t,pai386(hp)^.op1)
  505. { with tasm call near ptr [edi+12] does not
  506. work but call near [edi+12] works ?? (PM)}
  507. else if pai386(hp)^.op1t=top_ref then
  508. s:='near '+getopstr_jmp(pai386(hp)^.op1t,pai386(hp)^.op1)
  509. else
  510. s:='near ptr '+getopstr_jmp(pai386(hp)^.op1t,pai386(hp)^.op1);
  511. end
  512. else
  513. begin
  514. s:=getopstr(pai386(hp)^.op1t,pai386(hp)^.op1,pai386(hp)^.size,pai386(hp)^._operator,false);
  515. if pai386(hp)^.op3t<>top_none then
  516. begin
  517. if pai386(hp)^.op2t<>top_none then
  518. s:=getopstr(pai386(hp)^.op2t,pointer(longint(twowords(pai386(hp)^.op2).word1)),
  519. pai386(hp)^.size,pai386(hp)^._operator,true)+','+s;
  520. s:=getopstr(pai386(hp)^.op3t,pointer(longint(twowords(pai386(hp)^.op2).word2)),
  521. pai386(hp)^.size,pai386(hp)^._operator,false)+','+s;
  522. end
  523. else
  524. if pai386(hp)^.op2t<>top_none then
  525. s:=getopstr(pai386(hp)^.op2t,pai386(hp)^.op2,pai386(hp)^.size,
  526. pai386(hp)^._operator,true)+','+s;
  527. end;
  528. s:=#9+s;
  529. end
  530. else
  531. begin
  532. { check if string instruction }
  533. { long form, otherwise may give range check errors }
  534. { in turbo pascal... }
  535. if ((pai386(hp)^._operator = A_CMPS) or
  536. (pai386(hp)^._operator = A_INS) or
  537. (pai386(hp)^._operator = A_OUTS) or
  538. (pai386(hp)^._operator = A_SCAS) or
  539. (pai386(hp)^._operator = A_STOS) or
  540. (pai386(hp)^._operator = A_MOVS) or
  541. (pai386(hp)^._operator = A_LODS) or
  542. (pai386(hp)^._operator = A_XLAT)) then
  543. Begin
  544. case pai386(hp)^.size of
  545. S_B: suffix:='b';
  546. S_W: suffix:='w';
  547. S_L: suffix:='d';
  548. else
  549. Message(assem_f_invalid_suffix_intel);
  550. end;
  551. end;
  552. s:='';
  553. end;
  554. AsmWriteLn(#9#9+prefix+int_op2str[pai386(hp)^._operator]+suffix+s);
  555. end;
  556. {$ifdef GDB}
  557. ait_stabn,
  558. ait_stabs,
  559. ait_stab_function_name : ;
  560. {$endif GDB}
  561. else
  562. internalerror(10000);
  563. end;
  564. hp:=pai(hp^.next);
  565. end;
  566. end;
  567. procedure ti386intasmlist.WriteAsmList;
  568. begin
  569. {$ifdef EXTDEBUG}
  570. if assigned(current_module^.mainsource) then
  571. comment(v_info,'Start writing intel-styled assembler output for '+current_module^.mainsource^);
  572. {$endif}
  573. LastSec:=sec_none;
  574. if current_module^.output_format in [of_nasm,of_obj] then
  575. AsmWriteLn('BITS 32')
  576. else
  577. begin
  578. AsmWriteLn(#9'.386p');
  579. AsmWriteLn(#9'LOCALS '+target_asm.labelprefix);
  580. AsmWriteLn('DGROUP'#9#9'GROUP'#9'_BSS,_DATA');
  581. AsmWriteLn(#9#9'ASSUME'#9'CS:_TEXT,ES:DGROUP,DS:DGROUP,SS:DGROUP');
  582. end;
  583. WriteTree(externals);
  584. { INTEL ASM doesn't support stabs
  585. WriteTree(debuglist);}
  586. WriteTree(codesegment);
  587. WriteTree(datasegment);
  588. WriteTree(consts);
  589. WriteTree(rttilist);
  590. WriteTree(bsssegment);
  591. if not (current_module^.output_format in [of_nasm,of_obj]) then
  592. AsmWriteLn(#9#9'END');
  593. AsmLn;
  594. {$ifdef EXTDEBUG}
  595. if assigned(current_module^.mainsource) then
  596. comment(v_info,'Done writing intel-styled assembler output for '+current_module^.mainsource^);
  597. {$endif EXTDEBUG}
  598. end;
  599. end.
  600. {
  601. $Log$
  602. Revision 1.8 1998-05-06 18:36:53 peter
  603. * tai_section extended with code,data,bss sections and enumerated type
  604. * ident 'compiled by FPC' moved to pmodules
  605. * small fix for smartlink
  606. Revision 1.7 1998/05/06 08:38:32 pierre
  607. * better position info with UseTokenInfo
  608. UseTokenInfo greatly simplified
  609. + added check for changed tree after first time firstpass
  610. (if we could remove all the cases were it happen
  611. we could skip all firstpass if firstpasscount > 1)
  612. Only with ExtDebug
  613. Revision 1.6 1998/05/04 17:54:24 peter
  614. + smartlinking works (only case jumptable left todo)
  615. * redesign of systems.pas to support assemblers and linkers
  616. + Unitname is now also in the PPU-file, increased version to 14
  617. Revision 1.5 1998/05/01 07:43:52 florian
  618. + basics for rtti implemented
  619. + switch $m (generate rtti for published sections)
  620. Revision 1.4 1998/04/29 10:33:41 pierre
  621. + added some code for ansistring (not complete nor working yet)
  622. * corrected operator overloading
  623. * corrected nasm output
  624. + started inline procedures
  625. + added starstarn : use ** for exponentiation (^ gave problems)
  626. + started UseTokenInfo cond to get accurate positions
  627. Revision 1.3 1998/04/08 16:58:01 pierre
  628. * several bugfixes
  629. ADD ADC and AND are also sign extended
  630. nasm output OK (program still crashes at end
  631. and creates wrong assembler files !!)
  632. procsym types sym in tdef removed !!
  633. Revision 1.2 1998/04/08 11:34:17 peter
  634. * nasm works (linux only tested)
  635. }