The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: MusicalMike on July 24, 2005, 07:24:40 PM

Title: Traditionist Coding style
Post by: MusicalMike on July 24, 2005, 07:24:40 PM
Hello.
I have been programming for about 2 years. I started out with Javascript, moved to vb6, then to vb.net, then to c#, and finally to native c/c++. After finally learning the windows api in c, I decided to chalange myself a bit further and learn assembly language. To my great surprise, it was actualy pretty easy, atleast compared to c++. Now for my question. This is more of a best practices type question. I have always been a traditionalist in how I code. In my c code you will see a lot of hungarian notation for instance. Another good example of this is the fact that I generally prefere to use CreateWindow, rather than CreateWindowEx, (Since the first parameter will usually be null anyway) unless I have use for the extended Window Styles. Now as for my assembly code, my question is this. I personally prefere to use the cmp/jmp (or what ever conditional jump instruction I might need at the moment) pair rather than the high level syntax. I also prefere to use API calls rather than use the macros provided by MASM, and accept for when I am calling functions with long argument lists prefere the old method of pushing the arguments on the stack in reverse order and calling the function via the call instruction (just like in the old days). Is there any advantage or disadvantage to this traditionalist approach to assembly programming?
Title: Re: Traditionist Coding style
Post by: Eóin on July 24, 2005, 08:07:53 PM
Well manualy pushing of arguement is a bit tedious is it not? In practise it's probably more error prone/harder to debug. It makes source code with alot of api calls hard to read. Of course these are all personal things which you may feel differently about.

I suppose it really boils down to weither others will be reading your source code or not. If you think they will be then I'd suggest sticking to invoke for API calls but using cmp/j** over if/while.
Title: Re: Traditionist Coding style
Post by: James Ladd on July 24, 2005, 08:31:48 PM
Id use the invoke macro as manually pushing and balancing the stack can be error prone.
ie: you invariably forget something.
Besides, you should be spending more time on the finishing your good idea rather than
wrestling with the code to get it done.
Title: Re: Traditionist Coding style
Post by: hutch-- on July 24, 2005, 11:02:40 PM
Mike,

Both tecniques have their place and both have their advantages. Where you need more control or do things in non standard order, manualy push/call syntax is very useful but at the other end when you are shovelling trough a mountain of junk API calls, its just slow, harder to read and error prone.

Much the same with comparison/jump sequences, where you need real speed or additional flexibility, doing manual testing and branching on that basis does have some advantages in some circumstances but try and write a WndProc switch block for an aplication of any reasonable size and the automated methods are clearer, much faster to code and more reliable.

The trick with masm's preprocessor is to see it as an additional level of programmer control where you can actually control the form of code BEFORE it is fed to the assembler and this makes it a very powerful tool. Used in conjunction with library modules it gives capacity that is very efficient code, fast to code and generally more reliable as well.

The distinction to draw is what you get for the work you put into an app, putting your work into a high speed algo that can save large amounts of time in execution is worth the effort where creating te fstest messagebox on the planet most probably isn't.
Title: Re: Traditionist Coding style
Post by: tenkey on July 25, 2005, 03:31:59 AM
Using a CMP/JMP pair is very traditional, and if you want to code other processors (such as microcontrollers), it is often the only way.

I don't see much point in avoiding INVOKE. When I worked with one mainframe, we did all of our ASM system calls through macros supplied by the manufacturer. And if you get into microcontrollers, most projects won't require an OS.
Title: Re: Traditionist Coding style
Post by: MusicalMike on July 26, 2005, 01:04:21 AM
I guess I should have told you, I have always been a bit of a masochist when it comes to programming. I am known to use native c++ and api calls when c#.net would surfice (I actualy like c# but  I like to be chalanged more). But I see the point, I guess my final question is, is the code generated by the .if .else macros as fast as the cmp/goto pair?
Title: Re: Traditionist Coding style
Post by: hutch-- on July 26, 2005, 01:22:30 AM
Mike,

Its pretty close but you risk having a redundant jump from time to time if you jump to an option from witin the .IF block. It is not a performace issue but you end up with an occasional unused instruction. Where te .IF blocks really show their advantage is when you perform multiple testing on te same line. The code generation is very good.
Title: Re: Traditionist Coding style
Post by: raymond on July 27, 2005, 01:00:19 AM
For me, one of the advantages of the .if blocks is that I don't have to scratch my head to invent different labels for the jumps. And it can make the code a lot easier to read with proper indentations.

Raymond
Title: Re: Traditionist Coding style
Post by: GregL on July 27, 2005, 01:55:52 AM
I prefer the high-level syntax, it's easier to write and it's less error-prone.

Title: Re: Traditionist Coding style
Post by: psylem on July 28, 2005, 01:19:29 PM
I think it's good to learn the traditional methods first, otherwise you can't pinch algotihms from all the old text books (or do the micro controller thang). Once you know how it works though, give it up. If you want to show off to your mates, write a program that converts you code back to trad style so when you've finished you can pretend like you done it all hard core.
Title: Re: Traditionist Coding style
Post by: Mark Jones on July 28, 2005, 03:37:02 PM
Lately since the whole discussion about MASM and its funky use of brackets, I've been putting them around everything that references memory. Would this be considered "traditionalist coding style?"


        .if CapMsg  ; display one set of parameters
            mov [CapMsg],0                      ; only display one messagebox!
            invoke dw2hex,[nCode],addr Cap1      ; convert returned vals to strings
            invoke dw2hex,[wParam],addr Cap2
            invoke dw2hex,[lParam],addr Cap3
            invoke wsprintf,addr CapRes1,addr CapFmt1,addr Cap1,addr Cap2,addr Cap3
            push edi                            ; save edi
            mov edi,[lParam]                    ; EVENTMSG structure?
            assume edi:ptr EVENTMSG
            invoke dw2hex,[edi].message,addr Cap4
            invoke dw2hex,[edi].paramL,addr Cap5
            invoke dw2hex,[edi].paramH,addr Cap6
            invoke dw2hex,[edi].time,addr Cap7
            invoke dw2hex,[edi].hwnd,addr Cap8
            assume edi:nothing
            pop edi
            invoke wsprintf,addr CapRes2,addr CapFmt2,addr Cap4,addr Cap5,addr Cap6,addr Cap7,addr Cap8
            invoke lstrcat,addr CapRes1,addr CapRes2
            invoke MessageBox,[hWnd],addr CapRes1,0,MB_OK
        .endif
Title: Re: Traditionist Coding style
Post by: Mirno on July 28, 2005, 05:07:43 PM
The only time I've ever moved away from the invoke style call was one time where I was saving bytes (size optimising to a ridiculous point). By pushing manually you can push all the arguments then do several calls, this saves bytes by pushing a register instead of the memory location (also using xor edx,edx rather than push zero).


    invoke CreateMenu
    mov hMenu, eax
    invoke AppendMenu, eax  , MF_STRING, CM_REFRESH, ADDR M1
    invoke AppendMenu, hMenu, MF_STRING, CM_ABOUT, ADDR M2
    invoke AppendMenu, hMenu, MF_SEPARATOR, NULL, NULL
    invoke AppendMenu, hMenu, MF_STRING, CM_EXIT, ADDR M3

Becomes

    invoke CreateMenu
    mov hMenu, eax
    xor edx, edx

    push OFFSET M3
    push CM_EXIT
    push edx
    push eax

    push edx
    push edx
    push MF_SEPARATOR
    push eax

    push OFFSET M2
    push CM_ABOUT
    push edx
    push eax

    push OFFSET M1
    push CM_REFRESH
    push edx
    push eax
    call AppendMenu
    call AppendMenu
    call AppendMenu
    call AppendMenu


But this really is an extreme case, and not something you really want to be doing.

Mirno
Title: Re: Traditionist Coding style
Post by: tenkey on July 28, 2005, 10:00:53 PM
Quote from: Mark Jones on July 28, 2005, 03:37:02 PM
Lately since the whole discussion about MASM and its funky use of brackets, I've been putting them around everything that references memory. Would this be considered "traditionalist coding style?"

No.

The only other assembly language I've seen that uses bracketing characters around data address labels was for the Zilog Z-80. All the other non-x86 assemblers I can remember have no such need. They may (or may not) use brackets to indicate if a register name is used as an addressing register, as opposed to a data register. On some processors, brackets may mean indirect addressing from memory. It doesn't on the x86 primarily because the processor itself does not support that addressing mode.
Title: Re: Traditionist Coding style
Post by: Eóin on July 28, 2005, 11:56:33 PM
Well tenkey, FASM uses bracketing around memory references. The logic is that the variable name is really just an equate for its address value (be it absolute or relative) in memory and you would use brackets if you were entering the address so you use them with the name.

Its a minor and very personal thing I suppose, but it was one of the main reasons I switched to FASM.
Title: Re: Traditionist Coding style
Post by: hutch-- on July 29, 2005, 12:58:16 AM
I have never seen the square bracketing issue as anything other than a syntax requirement with some assemblers. TASM varies from MASM to ideal mode, NASM requires square brackets as does FASM but MASM does not require them around variable names at all but it will tolerate all sorts of superfluous bracketing as a style consideration.


mov var, eax
mov [var], eax
mov [[[[var]]]], eax


and a whole pile of nosense variations. Masm will let you write nonsense like,


    mov eax, [[[[1111]]]]


because it strips it back to,


    mov eax, 1111


I see it as very much the case of using a tool according to its documentation and with MASM, you are making the source ambiguous by using backets where they ae not required.

Some of the other assemblers around perform an abstraction of memory operand where MASM seperates an OFFSET from a stack location with different notation as they are different things.
Title: Re: Traditionist Coding style
Post by: Mark Jones on July 29, 2005, 01:01:21 AM
Jeez, is nothing simple and sacred anymore? :toothy
Title: Re: Traditionist Coding style
Post by: hutch-- on July 29, 2005, 01:16:54 AM
Mark,

The world is a malicious plot to kneecap you into cowering complaince where I am a "a Rafferty's Rules" man myself.  :bg
Title: Re: Traditionist Coding style
Post by: MusicalMike on July 29, 2005, 01:18:51 AM
Jeese, I didn't figure on my thread becomming so popular. In any event, a lot of people seem to be interested in the square bracket issue now. I happen to know the answer to that. Assemblers like fasm, gas, etc use a very different style from MASM and TASM (TASM is the next closest thing to MASM). Square brackets are traditionally used for addressing memory via the complex memory addressing modes, since this is built into the CPU MASM also supports this feature. Assemblers also allow you to use the subscript notation such as this; myLabel[0].
Title: Re: Traditionist Coding style
Post by: PBrennick on July 29, 2005, 01:07:29 PM
I would not say that masm does not support indirect addressing.  It just does it in another way.  Using OFFSET or ADDR is a form of indirect addressing in the sense that it tells the assembler it is NOT an indirect address because the variable contains the data.  A variable can be a pointer to another variable that contains the data.  This is indirect addressing.

Paul
Title: Re: Traditionist Coding style
Post by: Randall Hyde on July 29, 2005, 03:30:06 PM
Quote from: MusicalMike on July 29, 2005, 01:18:51 AM
Jeese, I didn't figure on my thread becomming so popular. In any event, a lot of people seem to be interested in the square bracket issue now. I happen to know the answer to that. Assemblers like fasm, gas, etc use a very different style from MASM and TASM (TASM is the next closest thing to MASM). Square brackets are traditionally used for addressing memory via the complex memory addressing modes, since this is built into the CPU MASM also supports this feature. Assemblers also allow you to use the subscript notation such as this; myLabel[0].

At the CPU level, indirect addressing is specified by various bit patterns in the opcode. Brackets have nothing to do with it. Syntactically, you could use parenthesis (as Gas does), an asterisk (as C/C++ does), a caret (as Pascal does) or any other syntactical form.

In standard (original) Intel syntax, identifiers in the symbol table carry sufficient information to let the assembler know if they are a memory location or something else, so the assembler can determine whether an identifier references memory just from the identifier. However, this takes a more sophisticated data structure in the symbol table and more complex code in the assembler itself. It is no wonder that hobby level assemblers eschew the Intel syntax and go with the use of brackets to signify memory access -- it's much easier to code.

In the early days of computer, assembly language syntax was kept as simple as possible because assemblers had to be small. Early computers didn't have much memory and you couldn't afford all the extra code and data to support a sophisticated syntax. Several "old-timers" got used to that simplistic syntax and grumbled when Intel syntax came along, but Intel's syntax is better for many well-understood software engineering reasons.

As to the "hobby-level" assemblers, that's a choice they made and they're going to have to live with it. Some prefer that syntax, but it has it's own drawbacks.
Cheers,
Randy Hyde
Title: Re: Traditionist Coding style
Post by: MusicalMike on July 29, 2005, 04:40:38 PM
(off topic) Wait, are you THE Randall Hyde the creator of the High Level Assembler?
Title: Re: Traditionist Coding style
Post by: PBrennick on July 29, 2005, 04:48:50 PM
[Grumble]

Is that an indirect grumble?  I sure am a grumbler, though.

Paul
Title: Re: Traditionist Coding style
Post by: Randall Hyde on July 29, 2005, 07:11:01 PM
Quote from: MusicalMike on July 29, 2005, 04:40:38 PM
(off topic) Wait, are you THE Randall Hyde the creator of the High Level Assembler?

One and the same.
Cheers,
Randy Hyde
Title: Re: Traditionist Coding style
Post by: Mark Jones on July 29, 2005, 08:56:51 PM
Wuh-oh, this thread is really goin' askew now. :toothy
Title: Re: Traditionist Coding style
Post by: tenkey on July 29, 2005, 10:18:39 PM
Quote from: Eóin on July 28, 2005, 11:56:33 PM
Well tenkey, FASM uses bracketing around memory references. The logic is that the variable name is really just an equate for its address value (be it absolute or relative) in memory and you would use brackets if you were entering the address so you use them with the name.
I should have stated that the Zilog assembler was the only non-x86 assembler that I've ever seen that uses bracketing (actually round brackets) in the same way as FASM/NASM/etc. I implied it in the sentence that followed.

Because we're talking about different syntaxes that describe exactly the same machine, I just view it all as window dressing. I have my preferences, but I have no problems with whatever style you choose. Heck, if I was interested enough, I'd create an assembly language that looked like the mainframe assembler I used to use.

The question has been about "traditional" coding style, which uses minimal syntax. As Randy mentions, this was true of the really old (and thus to my mind, the "traditional") assemblers.
Title: Re: Traditionist Coding style
Post by: Xor Stance on July 31, 2005, 11:40:07 PM
Pbrennick,

quote from AOA:

There are eight forms of this addressing mode on the 80x86, best demonstrated by the following instructions:

      mov( [eax], al );

      mov( [ebx], al );

      mov( [ecx], al );

      mov( [edx], al );

      mov( [edi], al );

      mov( [esi], al );

      mov( [ebp], al );


I know I haven't learn asm that much but its because I read asm only 1 minute and then play or do something else.
But now I have mature a little bit, and the bore is getting drown away fool genes let me stay.

That sucks that masm doesn't let you support a normal syntax from Intel, damn ms. But LEA direct addressing mode, I didn't know much about OFFSET and ADDR but I know there functions.

MusicalMike,

all was derive from machine language 0101 to 0101 asm, asm with macros, etc... You can try Goasm the tuts is where you learn quickly and fast. HLA has its own book AOA, the best for description among overall, Nasm has its own doc it can be handy and Masm32 only has iczelion. programmersheaven.com Asm > a tutorial for 16-bits Adams or Cat like that the best
for getting started at DOS old days and then in Webster again you have to find the formal doc from ms imo good. Before you get lost... I forgot the Intel manuals don't get lost like Linux devs that they don't know that they're doing in Intel.

Just a note in Go, the tutorial was maded to learn efficiently and fast you might find it difficult but that's how binary and hexadecimal numbers are useful. But much of the theory you must find it in HLA and the rest, asm is for people that earned a medallion for learning it like another language.