flat assembler
Message board for the users of flat assembler.
Index
> Main > is there any directive like the [cpu 8086]? |
Author |
|
hckr83 10 Feb 2007, 05:13
I have recently decided to switch to fasm(hooray for you) and well before I had used nasm...I have read and got the bits16, so now..is there any directive to make only 8086 code, much like how the [cpu 8086] worked in nasm
I am switching because of how horribly supported nasm is recently... plus when using the [cpu 8086] directive in it, it produces inaccurate 16bit jumps [edit] for those of you who found this thread with searching, see http://board.flatassembler.net/topic.php?t=6921 |
|||
10 Feb 2007, 05:13 |
|
DOS386 10 Feb 2007, 06:16
Quote: I have recently decided to switch to fasm(hooray for you) Quote: is there any directive to make only 8086 code, much like how the [cpu 8086] worked in nasm You probably hit a weak point of FASM, I also wanted to ask this. MA$M has Code: .386 There should be a directive like cpu 8086 (+ 80286, 80386, 80486, P1, P2, P3), resulting in an error when discovering an unsupported instrucion, like BSWAP after cpu 80386 http://nasm.sourceforge.net/doc/html/nasmdocb.html FASM.TXT unfortunately boasts with all instructions without mentioning the risks (minimal CPU, privileged). _________________ Bug Nr.: 12345 Title: Hello World program compiles to 100 KB !!! Status: Closed: NOT a Bug |
|||
10 Feb 2007, 06:16 |
|
Tomasz Grysztar 10 Feb 2007, 12:32
While with 8086/286/386 it was quite simple and straightforward, with more modern instructions sets that are often just turned on or off by a feature bits etc. it would be a more trouble than it is worth (in my opinion).
fasm generally tries to go for the totality of instruction set (note the undocumented "loadall286" and "loadall386" mnemonic), which also saves you a trouble when implementing routine variants for various processors within the single source. As for the 8086 programming, in the early days of fasm I proposed sometimes an 8086.INC file that looked like: Code: je equ short je jb equ short jb ; ...and so on for all conditional jumps macro shr val,cnt { times cnt: shr val,1 } macro shl val,cnt { times cnt: shl val,1 } ; ...and so on for all shift instructions to perform TASM-like conversion of code from higher processors to 8086 (not counting the instructions that are completely unsupported, that's a different story). |
|||
10 Feb 2007, 12:32 |
|
MCD 10 Feb 2007, 21:26
Tomasz Grysztar wrote: While with 8086/286/386 it was quite simple and straightforward, with more modern instructions sets that are often just turned on or off by a feature bits etc. it would be a more trouble than it is worth (in my opinion). That wuld also be the way I would have suggested it. Writing switches for every available x86 CPU-family and/or model would just overbloat fasm, so writing macros for each instruction (and even the special registers!) would be the way to go. It's just a shame that there is no "official" library for people that needs to code for older CPUs. That would be another interesting Fasm project should post this in Projects an idea section. 1 more suggestion for your example Tomasz, since hckr83 certainly wants some error messages to be displayed if anything else than 8086 is written: Code: ;example that disallows BSWAP, stop the assembling and display the error message bswap equ _bswap bswap eax I got 1 more feature request: Coder should be able to throw own compile time errors that would make Fasm stop with a defined error code, so you could write own error "handlers" like this: Code: macro bswap A{ display "8086 illegal instruction: bswap" error -1;Fasm should simply stop here } bswap eax _________________ MCD - the inevitable return of the Mad Computer Doggy -||__/ .|+-~ .|| || |
|||
10 Feb 2007, 21:26 |
|
rugxulo 11 Feb 2007, 02:26
Quote:
Shouldn't that be je equ je short?? Anyways, yes, I was thinking about this but too afraid to really say anything. Then again, all I wanted was "use16" to default to non-386 jumps (no "0F .. .. .." encodings!). I figured this could be done (in order of difficultly) via equ, macro ("if op1 in <>" to selectively make some jumps short by default), using an external tool like sed, or adjusting FASM's src. |
|||
11 Feb 2007, 02:26 |
|
MCD 12 Feb 2007, 00:11
Finally I have written an include file that disallows anything else than plain 8086, but thought it's quiet carefully written, it's not complete yet, but you can suretainly guess in what direction this goes when it's finished:
Code: _inc_8086: ;check if we are 16bits (use16) virtual mov ax,bx load .prefix0 from $$ end virtual if .prefix0 = 66h display "ERROR: 8086-program not compiled with use16!" end if ;note: 64bit registers, memory and addressing are completely ;forbidden in 16bit mode so we don't have to care about that from now on! ;define error messages .illegal_addr_size equ "Illegal address size" .illegal_operand_size equ "Illegal operand size" .illegal_regs equ "Illegal registers" .constants_not_allowed equ "Constants are not allowed" .shift_cnt_not_1 equ "Shift count not 1" ;this push-macro is rather complete, it only lack of 2 things: ;*pushing multiple values must be separated with commas instead of spaces ; (could maybe be solved with "match", no idea how to do) ;*errors are reported in this macro, so you will have a little overhead if you ; accidentially used a non-8086 feature. I guess there is no work around ; for this little problem with current fasm, since there is no way to make ; custom error messages that stops fasm from assembling your program macro push [A]{ local .instr .instr: ;32bit operands implicitly disallowed push A load .prefix0 from .instr .prefix1= 0 if (.prefix0 = 67h) | (.prefix0 = 66h) load .prefix1 from .instr+1 end if ;disallow constants if A eqtype 0 display .constants_not_allowed push ;disallow 32bit addresses else if (.prefix0 = 67h) | (.prefix1 = 67h) display .illegal_addr_size push ;disallow 32bit operands else if (.prefix0 = 66h) | (.prefix1 = 66h) display .illegal_operand_size push ;disallow control registers, how comes that Fasm got cr5-cr9? ;I didn't knew they even existed, are they documented somewhere? else if (A in <cr0,cr1,cr2,cr3,cr4,cr5,cr6,cr7,cr8,cr9>) display .illegal_regs push end if } pushw fix push pushd fix .illegal_instr ;this is the shl macro that basically disallows immediate values !=1 ;all other shift instruction macros are analogous macro shl A,B{ local .instr .instr: shl A,B load .prefix0 from .instr load .prefix1 from .instr+1 ;disallow shifts != 1 if (B eqtype 0) & (B <> 1) display .shift_cnt_not_1 shl ;disallow 32bit addresses else if (.prefix0 = 67h) | (.prefix1 = 67h) display .illegal_addr_size shl ;disallow 32bit operands else if (.prefix0 = 66h) | (.prefix1 = 66h) display .illegal_operand_size shl end if } ;... TODO: other instruction macros ;disallowing entire instructions like this movzx equ .illegal_instr ;... your task to complete ;prefixes must also be reimplemented as macros or else multiple prefixes would ;undergo the 8086-conformity checking and stuff like ;lock pop eax ;would re-allowing it! macro lock [A]{ common lock A } macro repz [A]{ common repz A } macro repnz [A]{ common repnz A } rep fix repz repe fix repz repne fix repnz Also usage is quiet simple, see this example program Code: use16 ;only8086.inc is the name of the above include file include "%SomeFunnyLibPath/only8086.inc" push ax,dx,cs;this should work shl dx,1;this too shl word [ax],1;this too push 10;not allowed shl ax,7;this neither shl ax,7;this neither push eax;this neither If I got some time in the next days/weeks, I will complete it I'm thankful for any suggestions _________________ MCD - the inevitable return of the Mad Computer Doggy -||__/ .|+-~ .|| || |
|||
12 Feb 2007, 00:11 |
|
rugxulo 14 Feb 2007, 03:16
Okay, here's my attempt at preventing 386+ jumps (0F .. .. ..). If a short jump is out of range, I do a simple workaround. (If you want to see what FASM would normally do, then change all je after Komenco: to jz (or do a quick sed -i '/Komenco/,$s/\<je\>/jz/' JMP16.ASM ... assuming GNU sed 4.x).
N.B. I have not written/understood a lot of macros very well, so this may be completely wrong. But anyways, here's my two cents ... Code: ; ---------------------------------------------------------------------- ; ; JMP16.ASM -- avoiding 386+ near jumps (0Fh .. .. ..), if unnecessary ; ; Tuesday, February 13, 2007 7:56pm ; ; rugxulo AT bellsouth SPAM_SUX (dot) net ; tested w/ FASMD 1.67.18 ; ; *** N.B. Only 'je' is done, for now (I hope it's correct !!) *** ; ; ---------------------------------------------------------------------- ; ; ( complete list of all kinds of jumps, from TABLES.INC): ; ; ja,jb,jc,je,jg,jl,jo,jp,js,jz,jae,jbe,jge,jle,jmp,jna,jnb,jnc, ; jne,jng,jnl,jno,jnp,jns,jnz,jpe,jpo,jcxz,jnae,jnbe,jnge,jnle ; ; ( we're ignoring jecxz,jrcxz ) ; ; ---------------------------------------------------------------------- macro goto cond,me { @@: if ((me < @b) & (@b-me > 126)) | ((me > @b) & (me-@b > 129)) jn#cond @f jmp me else j#cond me end if @@: } macro je a*,b { if a eqtype short short fix goto e,b else goto e,a end if } org 100h Komenco: times 127 nop ; short jump here = max. 126 je Komenco ; should be 2-byte short jump Okay: times 128 nop je Fino times 128 nop ; short jump here = max. 127 Fino: ret ; EOF EDIT: The only way to really know if your code outputs unsupported opcodes is to disassemble the binary after assembling. BIEW color-codes instructions according to cpu set (but only interactively). Of course, since the 8086 only supports 6-byte opcodes max., you could always use diStorm64 (updated today!) and do a grep for '(0[7-9])\|([^0][0-9])', but that is somewhat unreliable. (At least NDISASM reports 386+ jumps as "near", so you can search for that.) |
|||
14 Feb 2007, 03:16 |
|
MCD 14 Feb 2007, 16:24
if anyone is interested in an 8086only include file, I'm currently writing one, but this will suretainly take a while again
Last edited by MCD on 16 Feb 2007, 06:46; edited 1 time in total |
|||
14 Feb 2007, 16:24 |
|
MCD 16 Feb 2007, 06:46
*drums* here it is, a full featured include file for fasm, that will bark if anything else than 8086 instructions were used.
simply use it like this: Code: use16 include "%SomeFunnyLibPath/only8086.inc" push ax,dx,cs;this should work shl dx,1;this too shl word [ax],1;this too push 10;not allowed shl ax,7;this neither shl ax,7;this neither push eax;this neither I'm thankful for any suggestions. the only thing I didn't figured out was how to make push/pop macros that accept space separated operands when pushing/poping multiple ones. Instead you must write something like: Code: push ax,bx,cx when pushing multiple operands. Does anyone know how to fix this? EDIT: attachment removed, there is a newer version in a later post _________________ MCD - the inevitable return of the Mad Computer Doggy -||__/ .|+-~ .|| || Last edited by MCD on 17 Feb 2007, 04:15; edited 1 time in total |
|||
16 Feb 2007, 06:46 |
|
LocoDelAssembly 16 Feb 2007, 13:39
Quote: when pushing multiple operands. Does anyone know how to fix this? Thanks for posting your work |
|||
16 Feb 2007, 13:39 |
|
rugxulo 16 Feb 2007, 20:54
MCD, my example above is generating 386+ jumps (four bytes: 0Fh .. .. ..) even when including your ONLY8086.INC file.
"je My_label" should have "short" in the middle if you want to stop and report an error. Otherwise, you'll have to do some kind of workaround like I did above. |
|||
16 Feb 2007, 20:54 |
|
DOS386 17 Feb 2007, 01:35
Tomasz wrote:
Quote: While with 8086/286/386 it was quite simple and straightforward, with more modern instructions sets that are often just turned on or off by a feature bits etc. it would be a more trouble than it is worth (in my opinion). OK, the "modern" stuff like MMXxxx/SSEyyy would cause trouble But a method of limiting to official instructions of 8086, 80286, 80386 and 80486 would be useful. _________________ Bug Nr.: 12345 Title: Hello World program compiles to 100 KB !!! Status: Closed: NOT a Bug |
|||
17 Feb 2007, 01:35 |
|
MCD 17 Feb 2007, 04:13
rugxulo wrote: MCD, my example above is generating 386+ jumps (four bytes: 0Fh .. .. ..) even when including your ONLY8086.INC file. Thanks for the hint, I had completely forgetten this in the 2day-rush I coded that. (I never thought I could do such a think so fast) There is another important thing I had forgotten: I haven't checked instructions for bad fs/gs segment registers, which aren't allowed on 8086 neither. But here is a revised version of my "only8086.inc" which fixes all that: (except that you still have to write "push ax,bx,cx" with commas )
_________________ MCD - the inevitable return of the Mad Computer Doggy -||__/ .|+-~ .|| || |
|||||||||||
17 Feb 2007, 04:13 |
|
rugxulo 18 Feb 2007, 05:58
MCD, I tried downloading it but at 300bps, my 8086 isn't quite done yet (I might have to wait a few years). Anyways, kudos!
|
|||
18 Feb 2007, 05:58 |
|
MCD 18 Feb 2007, 07:31
rugxulo wrote: MCD, I tried downloading it but at 300bps, my 8086 isn't quite done yet (I might have to wait a few years). Anyways, kudos! OMG... your modem is even older than my v90 ROFL but even with 300bps, it should be downloaded ~ 10-15 minutes, so where is the problem? _________________ MCD - the inevitable return of the Mad Computer Doggy -||__/ .|+-~ .|| || |
|||
18 Feb 2007, 07:31 |
|
rugxulo 18 Feb 2007, 20:00
MCD wrote:
Bah, your math skills have slayed my joke! (*cough* *cough* ... ack) It'd be even faster to download if you .ZIP'd it. P.S. Actually, my old 486 (from 1994) had a 2400 bps modem, initially. (And nowadays we think 56k is slow!) EDIT: Yes, well, I forgot that most websites have ads, heavy graphics, and sometimes even video, flash, or other multimedia to bloat up everything (ugh). (Yes, I know, you can disable most of that, but still, kinda rampant misuse of embedded media ... hint hint, MySpace.) |
|||
18 Feb 2007, 20:00 |
|
MCD 19 Feb 2007, 22:28
rugxulo wrote:
maybe I falsely assumed that you meant 300 bits/second with 300bps, but I gues you meant 300 baud/second BTW: how do you manage to download the Fasm archive with THAT high connection speed (even the smalles, Linux version is about 178kByte)? rugxulo wrote:
well, I could make a special small version where the most often used symbols are abbreviated since they take up much space. would you also take bz2-files? since this compression is even better for text files. rugxulo wrote:
Actually, I still have a combined RS232/RS485 external modem with 1200 baud/s laying somewhere around here, but I can't figure out where I left that? _________________ MCD - the inevitable return of the Mad Computer Doggy -||__/ .|+-~ .|| || |
|||
19 Feb 2007, 22:28 |
|
rugxulo 20 Feb 2007, 05:25
MCD wrote:
FASM.EXE is the first file in the DOS distro, <sarcasm> so I just tell my 300 bps modem to stop downloading after 50k or so, and I can manually fix the truncated .ZIP file to allow extraction. </sarcasm> The best download method would be PPM compression (e.g. UHarc), but if someone doesn't have that, I guess I'd just suggest something simpler (sfx for .LZH or .ESP is about 3k). |
|||
20 Feb 2007, 05:25 |
|
rugxulo 12 Mar 2008, 04:06
Trixter from Oldskool.org recently gave me a few comments about this ONLY8086.INC file:
Quote:
|
|||
12 Mar 2008, 04:06 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.