Normally I wouldn't make a thread on voting type of thing because most of the times their kinda pointless and just take up space and annoy people but I'm kinda between a rock and a hard place on this.. This is really a question for Shoo, since he was the one that told me about it. I guess it's for other's who are also using it too, anyhow the question is, is FASM really worth it? I mean I been using MASM, and there's ALOT of quirks that I really don't like about it, things don't seem to behave the way you'd expect them to, which is why I usually find open source stuff more predicitable (since that stuff is developed for the people by the people instead of by a corporation like Microsoft). I been trying to convert my latest project, a demo I been working on, to FASM syntax, and I'm really struggling through it, I mean I'm managing to get through the compile errors but I'm not certain that the lines are identical in terms of definition and result (all I know is that little by little the compiler gets a little further). Should I continue to persue making the move to FASM or should I stick with MASM? I know their is plus'es and minus'es to each and that theirs gonna be a pretty big divide on this, I'm just looking for an overall number of how many like it versus how many don't, that sort of thing. More or less 2 main things that I need is for a compiler that deals with


  • variable accessing the value of the element in an array (like mov ecx, variable  ;and acctually behaving like that, not like it allows it and behaves really off the wall)

  • Bracket usage (for the most part) meaning the value/contents of... not the memory address and that it doesn't assume that with or without brackets it means what it thinks it should mean *cough* how masm says you don't need brackets *cough*



At the moment I think my biggest issue is with MASM assuming things and giving totally unpredictable results, and FASM's syntax.. When I say syntax for example in fasm this seems to be invalid
LOCAL TempVariable:DWORD
instead it shoudl be
TempVariable dw

now to me that looks extremely bizarre, looks more like a single operand opcode to me.. and I kinda always though those 2 letter datatypes were not quite the same as the full spelled out ones.. ex: dw == dword??
also the sections definitions, it seems to not matter where your sections go as long as their defined, that's ok but I'm not certain on this, because it's very undocumented (the compiler that is), I only gathered that info by examining the few examples the compiler does come with and that's what I've noticed
And asside from the location of the section definitions, the section definitions themselves are really odd
ex:  section '.bss' readable writeable        ;.bss wtf??
in MASM it was just .data?
I mean I guess I can gather from that, it means that the memory space for the .data? sections is readable and writeable, but it's so "ugh" looking.. lol  (Guess it's prolly not to bad for someone that's a veteran asm coder, or someone that started out using it, but for me it's a headache)

I really want to stay as true as possible the the assembly language but at the same time I'd like an asm compiler that reacts a little bit more on par as something as a hll but without the hll bloat/(code)

Cross platform would be nice, but at this point in time I'd settle for something not cross platform, I'm not good enough to I can fight these many language issues at once. I'd like to get really really really good first, then I'd feel like I'm not overwhelmed with problems and results I didn't expect.
Posted on 2005-09-25 14:57:21 by EtErNiTy
Personally I always felt more comfortable with FASM.

P.S. FASM has macros to support LOCAL TempVariable:DWORD, though I believe you have to use lowercase for the word local.
Posted on 2005-09-25 15:28:05 by Eóin
The real question you have ask is, how many times will you come to this conclusion before you implement it ;)

Amateur programming is as much about enjoyment as it is conformance to the tools at hand, I am sure you and many other people would love to see a FASM32 package as well... so you might want to get together with some people on that ;)
Posted on 2005-09-25 15:36:15 by SpooK
EtErNiTy,

Any tool involves bothering to properly learn how it works, be it MASM, FASM GoAsm, NASM, GAS or any others. If you are interested in muliport assembler, FASM and NASM both have the capacity with FASM being a better supported tool. MASM is and will stay a Windows tool and that is primarily its advantage, it is dedicated to a platform.

The vast majority of MASM source code is not produced by Microsoft but by programmers who use it so its a matter of style that you may personally like or dislike. If you really want open source GPL assembler programming in Linux, use (GNU)AS but note that it has few facilities for being written by hand as it is mainly a backend for GCC.
Posted on 2005-09-25 20:18:42 by hutch--
When I said the thing about the open source stuff, I didn't mean like the examples included are written better, I just meant that when the assembler was developed that it was prolly geared more towards what the general public wanted.

Perhaps it's something that can be answered easily though, right now my biggest gripe with masm is the usage of registers. Now its possible is just assembly in general, but somehow I can't help but to think that it's possibly the compiler (maybe it's not strict enough during compile time?) 

If I do for instance
(I used HLL constructions only because with all the local labels and jmp'ing around it made it really difficult to debug)


      mov TempVariable1, 0
      push esi
      mov esi, 0

      .WHILE esi < tSmallTextCounter
            ;inc TempVariable1
            ;.IF TempVariable1 > 4
            ;    ;Loop through and bump each element pointer up by 1
            ;    push esi
            ;    mov esi, 0
            ;    push ebx
            ;    .WHILE esi < tSmallTextCounter
            ;        inc esi
            ;        mov ebx, TextElementIndex
            ;        inc ebx
            ;        .IF ebx > 16
            ;            mov ebx, 1
            ;            mov TextElementIndex, ebx
            ;        .ELSE
            ;            mov TextElementIndex, ebx   
            ;            add TextElementIndex, 1
            ;        .ENDIF
            ;    .ENDW
            ;    pop ebx
            ;    pop esi
            ;    mov TempVariable1, 1
            ;.ENDIF

            ;inc ecx
            inc esi

            ;mov TempX1, 356            ;200 base width, plus 100 extra width as noted in the declarations section of the source
            mov TempX1, 200             
            sub TempX1, esi
            ;mov ecx, TempX1

            mov ebx, TextElementIndex
            mov IndexValue, ebx

            mov ebx, TextPosOffsetMatrix
            mov TempY1, ebx
            add TempY1, 20
            ;mov ebx, TempY1
           
            invoke DrawLCDText, ADDR TempX1, ADDR TempY1, LCDTEXTSIZE_SMALL, ADDR tSmallText1
                ;push tSmallText1
                ;push LCDTEXTSIZE_SMALL
                ;push TempY1
                ;push TempX1
                ;call DrawLCDText

      .ENDW
      pop esi

Holy crap look out she's gonna blow!

but if I do...  Hope you all can follow this, it's pretty crazy

      mov TempVariable1, 0
      push esi
      mov esi, 0
      push ecx
      mov ecx, 0
      jmp @WhileESI_LT_tSmallTextCounter
     
      @WhileESI_LT_tSmallTextCounter:
            cmp ESI, tSmallTextCounter
            je @EndWhile1
            ;.WHILE esi < tSmallTextCounter
            inc TempVariable1
            cmp TempVariable1, 4
               

            jg @TempVariable1_GT_4_1
                @TempVariable1_GT_4_1:      ;.IF TempVariable1 > 4
                        ;Loop through and bump each element pointer up by 1
                        push ecx
                        mov ecx, 0
                        push ebx
                        jmp @TempVariable1_GT_4_2
                            @TempVariable1_GT_4_2:     
                                inc esi
                                cmp esi, tSmallTextCounter  ;.WHILE esi < tSmallTextCounter
                                jg  @FinishTempVariable1While2
                                mov ebx, TextElementIndex
                                inc ebx
                                cmp ebx, 16
                                jge @EBX_GTET_16
                                jl @EBX_LT_16
                               
                                @EBX_GTET_16:
                                    mov ebx, 1
                                    mov TextElementIndex, ebx
                                    jmp @TempVariable1_GT_4_2
                                @EBX_LT_16:
                                    mov TextElementIndex, ebx   
                                    add TextElementIndex, 1
                                    jmp @TempVariable1_GT_4_2
                                   
                            jmp @TempVariable1_GT_4_2
                            @FinishTempVariable1While2:
                                    pop ebx
                                    pop esi
                                    mov TempVariable1, 1
                                    jmp @ContinueWhile1
            @ContinueWhile1:
            inc esi

            mov ebx, TextElementIndex
            mov IndexValue, ebx

            ;mov TempX1, 356            ;200 base width, plus 100 extra width as noted in the definitions section of the source
            mov TempX1, 200             
            sub TempX1, esi
            ;mov ecx, TemX1
           
            mov ebx, TextPosOffsetMatrix
            mov TempY1, ebx
            add TempY1, 20
            ;mov ebx, TempY1
           
            invoke DrawLCDText, ADDR TempX1, ADDR TempY1, LCDTEXTSIZE_SMALL, ADDR tSmallText1
            ;invoke DrawLCDText, TempX1, TempY1, LCDTEXTSIZE_SMALL, ADDR tSmallText1
            ;invoke DrawLCDText, ecx, ebx, LCDTEXTSIZE_SMALL, ADDR tSmallText1
            ;invoke DrawLCDText, , , LCDTEXTSIZE_SMALL, ADDR tSmallText1

                ;push tSmallText1
                ;push LCDTEXTSIZE_SMALL
                ;push TempY1
                ;push TempX1
                ;call DrawLCDText
                jmp @WhileESI_LT_tSmallTextCounter
      @EndWhile1:
        pop ecx
        pop esi

        ; --- Blit the drawn LCD onto the back buffer ---
  invoke BitBlt, hBackDC,0,0,+WindowWidthSizeOffset, +WindowHeightSizeOffset, hLCDDC, 0,0, SRCCOPY

  ; --- Blit the monochrome label onto the back buffer ---
      invoke BitBlt, hBackDC,0,0,+WindowWidthSizeOffset, +WindowHeightSizeOffset, hLabelDC, 0, 0, SRCAND

  ;pop esi
        ; Draw the backbuffer onto the main window:
  invoke BitBlt, hDC,0,0,+WindowWidthSizeOffset, +WindowHeightSizeOffset, hBackDC, 0,0, SRCCOPY

        ; Stop painting:
  invoke EndPaint, hWnd, ADDR ps

It compiles and runs, but I get nothing on the LCD backdrop

Now to me on the surface I see nothing wrong with that code other than that their may be missing brackets where need be and extra brackets where they need'nt be. But with MASM being so loose on the compile rules it's tough to tell because it just lets it go through as one of the big things it boasts is that you don't need brackets.. That kinda defeats the purpose of assembly. I'd like to know exactly what's going on in the background not what can be assumed or guestimated.. Which is why I keep leaning towards going with FASM, it seems to be a bit more strict.. It's just the syntax is different, and the requirement to introduce different sets of include files means all the variable names accrossed all the code, etc have to be renamed and so forth..

The code above compiles and runs, but I get nothing as output on the lcd backdrop of the window. I can't help but to think if the compiler was more strict about how things are done or if it behaved more on par with what one would expect, I wouldn't be having issues like these.. I've must've read like 2 or 3 different tutorials on just how arrays work in asm, and they all kinda differed slightly, and I'm scraping the bottom of my own personal knowledge-barrel as to what else to try. One thing has always been said accrossed all the tutorials I've read is that there's 4 generic registers (ax,bx,cx,and dx and in win32 it's e-prefixed for extended or ehanced).. All the tutorials say that the middle letter means a specific thing like a  = accumulator, b = base, c = <don't recall> and d  = data (that's abcd.. I find it hard to beleive that it just so happends  that these registers go in order of the alphabet yet have the specific purpose up above mentioned.. But none of the tutorials talk about what you can use with specifically what type of data and in what construnction. Like they don't go into the real finite details that apparently I need  :?: o.O

EDIT: Added converted Non-HLL code.
Posted on 2005-09-25 22:32:44 by EtErNiTy
what LCD are you using?
Posted on 2005-09-25 23:08:47 by comrade
I'm using the LCD source in Example 6.. It's pretty heavily modified though, but you should be able to peice together that source with what I did and figure out about what the source code I have now looks like, unless you want me to attach it as a file to the thread?

The original source the LCD CD Player was written by
(C) 2000 by Thomas Bleeker . http://exagone.cjb.net

More or less the only thing that's left over is the lcd functions and the empty template-shell of a standard windows app
Posted on 2005-09-25 23:14:10 by EtErNiTy

If you really want open source GPL assembler programming in Linux, use (GNU)AS

Umm, why not use FASM? Runs on and produces output for linux, bsd, win32 ...  and is a lot more comfortable than GAS anyway.


invoke BitBlt, hBackDC,0,0,+WindowWidthSizeOffset, +WindowHeightSizeOffset, hLCDDC, 0,0, SRCCOPY

That looks preeeeetty wrong to me. If this even assembles, I guess ALIGNED_WIDTH and WINDOW_HEIGHT must be constants. WindowWidthSizeOffset and WindowHeightSizeOffset probably aren't. This looks pretty nasty :)

My suggestion would be to strip down the original MASM sample as much as you can, keeping the functionality you need, *and* keep the high-level syntax so that it still works. When you have a (working) exe with the stripped down functionality you need, then concentrate on making it work in FASM.

To make the conversion easier, assemble with "/Zi" and use a decent disassembler like IDA (free version should do), and compare the low-level listing to the high-level MASM code.
Posted on 2005-09-26 00:55:22 by f0dder
EtErNiTy,


Now to me on the surface I see nothing wrong with that code other than that their may be missing brackets where need be and extra brackets where they need'nt be. But with MASM being so loose on the compile rules it's tough to tell because it just lets it go through as one of the big things it boasts is that you don't need brackets.. That kinda defeats the purpose of assembly. I'd like to know exactly what's going on in the background not what can be assumed or guestimated.. Which is why I keep leaning towards going with FASM, it seems to be a bit more strict.. It's just the syntax is different, and the requirement to introduce different sets of include files means all the variable names accrossed all the code, etc have to be renamed and so forth.


Any assembler is "strict" in that you have a given set of opcodes on any piece of x86 hardware that must be used in a particular way. This characteristic is dictated by hadware, not assemblers. With MASM, it uses the historical Intel syntax where local and data section memory operands are named and while it will tolerate superflous brackets, it does not use them or need them. FASM is written to use square brackets around memory operands so you must use them in FASM. The confusion arises when someone tries to use the syntax of one tool with another where it is simply a matter of learning the syntax of the tool you use.

With FASM as in MASM, if you want to know exactly what is going on with code, you will have to avoid the high level macros and the like and code in mnemonics only. Its a lot more work, a lot more error prone and a lot slower but it will do exactly what you want. The best way I know of converting high level syntax to mnemonics is to build it in MASM with a number of NOPS in front of it, run DumpPE to get the disassembly, find the disassembled code from the nops and if you have the masm32 project, get a QE plugin that will format DumpPE output back to near human readable assembler.

That will make your porting to FASM a lot easier as the FASM macro versions of hll syntax are not properly compatible with MASM.

f0dder,


Umm, why not use FASM? Runs on and produces output for linux, bsd, win32 ...  and is a lot more comfortable than GAS anyway.


GAS has a massive user base with it being the back end for GCC and it is a very low level assembler so for someone who wants to write true low level code, it probaly cannot be beaten in Linux.

Regards,

hutch at movsd dot com
Posted on 2005-09-26 02:28:00 by hutch--


Umm, why not use FASM? Runs on and produces output for linux, bsd, win32 ...  and is a lot more comfortable than GAS anyway.

GAS has a massive user base with it being the back end for GCC and it is a very low level assembler so for someone who wants to write true low level code, it probaly cannot be beaten in Linux.


You don't have a lot of people actually writing code in GAS, though - exactly because it's mainly a backend for GCC and wasn't written to actually write assembly with.

If GAS was a nice tool, people wouldn't be using nasm and fasm for linux, bsd, et cetera :)
Posted on 2005-09-26 02:34:52 by f0dder
acctually beleive it or not

invoke  BitBlt, hBackDC,0,0,+WindowWidthSizeOffset, +WindowHeightSizeOffset, hLCDDC, 0,0, SRCCOPY

was part of the original code lol      only thing I did was the +WindowWidthSizeOffset and Height Offsets which are denoted at the top of my source as equ's  I used them throughout, so it's all ok  -- I got tired of changing the window size back to original and modified size, now I just have to change it in one place (at the top of my source), if I change it to 0, the window goes back to the original example's size


It's not so much the macro definitions of fasm that get me, it's the whole different set of includes files, new include files mean new names for defined (objects?), eample they use WS_HREDRAW and WS_VREDRAW instead of WM, not a big deal except I had to open the include files just to figure out that the name they(whoever wrote the include files) were using was 1 letter different, and that's all throughout the code, almost any and all constants will have to be figured out first and then changed. The macro definition stuff I thought went pretty easily, only odd thing I thought about it though was that you don't appear to have to declare the data types of the parameters of the macro.
Posted on 2005-09-26 07:05:33 by EtErNiTy
Actually it really is WS_HREDRAW and WS_VREDRAW - Check your include files again ;)
Posted on 2005-09-26 08:01:45 by JimmyClif

If GAS was a nice tool, people wouldn't be using nasm and fasm for linux, bsd, et cetera.


I imagine if GAS was not the premium assembler tool for Linux, it would not be used for manual code in the bits of Linux kernel code I have seen.
Posted on 2005-09-26 11:23:32 by hutch--
Wasn't the Linux kernel around before Fasm came along?

Wouldn't it be crazy to switch assemblers for existing 'working' code inside something as important as a Kernel even if it was a way superior piece of software?

Posted on 2005-09-26 11:32:30 by JimmyClif
Exactly, Jimmy. I'd wager that for ~95% of the projects where GAS is used, it's because GAS is the oldest assembler and is available on all distros.

I don't wish to see this (d)evolve into a flamewar, but advising people to use GAS is plain wrong - it's akin to advise people to use debug.com because it's available on all windows machines.
Posted on 2005-09-26 11:37:29 by f0dder
Its the fervour in which one assembler is sold that brings the response. We all know FASM is a good tool that will keep getting better but its not the only tool and there is no pervasive argument that it is better than many others. GAS is a very well known tool in Linux and it is perfectly suitable for true low level assembler programming. It is always up to date with all of the lates instructions and it has a perfectly good preprocessor, its called GCC.

As with MASM in Windows that has the track record at the OS production level in performance critical code, GAS has the track record in Linux with the OS production level in performance critical code.

> but advising people to use GAS is plain wrong

Inflicting dogma of this type is ill advised at best, a programmer who choses to write low level Linux code with GAS, with or without GCC has no need to take notice of comments of this type when many assembler programmr WANT TO WRITE LOW LEVEL CODE.

Regards,

hutch at movsd dot com
Posted on 2005-09-26 18:40:24 by hutch--
EtErNiTy, regarding your initial question, my answer is positively Yes. And actually the trouble to move from Masm to Fasm equals to the time spent to read the documentation, specially the win32 specific chapter (Total read of about 12 pages)

Fasm macros can mimick many Masm syntax constructs, however I would suggest to use a disassembled (with symbols) list (i.e. ollydbg) and then start working on it. Your code will look a lot cleaner. A spreadsheet also helps a lot on this process.
Posted on 2005-09-27 15:41:52 by pelaillo
Yeah I decided to suck it up and just to keep on plugging away at the conversion to fasm from my masm code. It's a hassle but the fasm compiler definatly seems to require you to be more specific about stuff which is something that I really appreciate.. Masm was awesome, but to me personally, I think it seems better for someone just getting their feet wet in assembly.

I've had years of just tinkering around in asm, but nothing of the sort of start to finish outright coding in asm. The experience I have had was mostly in 16bit dos stuff with interrupt vectors and basic simple stuff, and yes, my choice of assembler, was infact debug lol. It was HORRIBLE, I had to either learn how to count bytes and factor in opcode byte sizes so that my conditionals jumped to the right areas, or I had to fill in part of the code, see where the offset was, re-do the code from scratch again and use that offset.. Needless to say my progs were extremely small because of the hassle. In win32asm the experiences I have had mostly were disassembling online games to try to find packet encryption stuff to mimic a server (It was more for the challenge than anything, I bought every single one of those games) or to find hidden features.

Masm seems like it'd be really good for someone who has never even seen the 3 letter abreviation (sp?), jmp. As it allows people to focus on the language and less about the nitty gritty stuff.. Problem for me is, is at this point in my learning curve, I'm past all that, it's the nity gritty stuff that I need to understand. And the nitty gritty stuff is done slightly different from one compiler to the next. And I feel if I stay in MASM I'm limiting myself, because while I have no future plans to code in asm on Linux (I do know and use the OS on my other computer), the back-of-your-mind thought that you can write in it if you wanted is nice and comfy :P    I may even start to use the old-school call function instead of invoking stuff, just to really get into it :P 

Now granted, I know MASM does support calls and stuff like that, but it seems like it mostly encourages focusing on just the language and leaving the details to itself, which is cool, I'm not by any means knocking it, I knew going into writting this thread that choice of compiler is rather personal, and I think I got all the information neccessary to make an educated decision, so thanks very much guys, the input was extremly valuable! :)
Posted on 2005-09-27 20:30:09 by EtErNiTy