The MASM Forum

General => The Campus => Topic started by: Zen on September 27, 2016, 05:57:13 AM

Title: 20 Basic Practices in Assembly Language Programming
Post by: Zen on September 27, 2016, 05:57:13 AM
Another MASM Assembly Language Programming article from CodeProject:
20 Basic Practices in Assembly Language Programming, CodeProject (http://www.codeproject.com/Articles/1116188/Basic-Practices-in-Assembly-Language-Programming), by Zuoliu Ding.

...Intended,...I think for novices,...and, me,...:bgrin:
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: rrr314159 on September 27, 2016, 09:41:25 AM
Considering he's attempting the impossible - a quick summary of assembler for novices - the article is quite good. He's too casual about using xchg which locks memory and therefore is slow. Maybe that only matters in a multi-core environment? - But of course that's standard these days. More nits could be picked; no such article can satisfy everyone, but it's a good try. If you don't think so, let's see you do better!
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: hutch-- on September 27, 2016, 11:31:18 AM
With a quick scan, his reference material looks OK and much of it is just good programming practice but nothing beats the Intel manuals once you can get your head around them. I am always wary of any form of "politically correct" notions of how you write code and particularly with assembler code, architectural freedom is one of its greatest advantages. Others have written optimisation techniques, Agner Fog did very influential work as well as one of the Intel manuals but nothing beats the clock, design it, time it and keep going until the numbers don't get any lower.  :biggrin:

After that, then try it on different processor versions and learn the joys of average performance across a variety of different processors.  :P

XCHG was slow on a single core PIV, it never got any better on multicore hardware. Try and forget old DOS style instructions, they were super heros on a 286, anything committed to processor microcode is there for backwards compatibility reasons.
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: Gunther on September 27, 2016, 08:14:16 PM
Quote from: Zen on September 27, 2016, 05:57:13 AM
20 Basic Practices in Assembly Language Programming, CodeProject (http://www.codeproject.com/Articles/1116188/Basic-Practices-in-Assembly-Language-Programming), by Zuoliu Ding.

The article is good for novices. But there are other sources, too.

Quote from: hutch-- on September 27, 2016, 11:31:18 AM
... but nothing beats the clock, design it, time it and keep going until the numbers don't get any lower.  :biggrin:

That's the right approach.

Gunther
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: jj2007 on September 27, 2016, 09:41:23 PM
Quote from: rrr314159 on September 27, 2016, 09:41:25 AMMore nits could be picked;


6. Another good reason to avoid PUSH and POP (http://www.codeproject.com/Articles/1116188/Basic-Practices-in-Assembly-Language-Programming#good-reason)

QuoteIf you forget to make PUSH and POP in pair, an error could happen, and Hutch will eat you alive
:P
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: hutch-- on September 28, 2016, 01:21:08 AM
 :biggrin:

> and Hutch will eat you alive

I can tolerate people doing stupid things as long as they don't try and inflict it on me.  :P
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: rrr314159 on September 28, 2016, 01:54:09 AM
Quote from: Gunther on September 27, 2016, 08:14:16 PM
Quote from: hutch-- on September 27, 2016, 11:31:18 AM
... but nothing beats the clock, design it, time it and keep going until the numbers don't get any lower.  :biggrin:

That's the right approach.

Agree 100%, when you want the fastest code rely only on your own clock timings. However - we're talking "novice" here.

A beginner shouldn't worry about speed so much, there's a lot more to learn. For instance, they should be shown how to study coding examples, like those from masm32 libraries. Macros are often neglected - that's one good thing about this tutorial, it goes into them a fair amount. How to find bugs. Modular code design. Common errors to watch out for, as in jj2007's "tips, tricks and traps" - like eax can get blown away by a Windows call. This tutorial mentions ecx's volatility in loop instructions. That sort of thing is more important for beginners.

Generally, learning all those instructions and what to do with them is the hard part, worry about speed later.
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: Gunther on September 28, 2016, 09:49:38 AM
Hi rrr314159,

Quote from: rrr314159 on September 28, 2016, 01:54:09 AM
Agree 100%, when you want the fastest code rely only on your own clock timings. However - we're talking "novice" here.

A beginner shouldn't worry about speed so much, there's a lot more to learn. For instance, they should be shown how to study coding examples, like those from masm32 libraries. Macros are often neglected - that's one good thing about this tutorial, it goes into them a fair amount. How to find bugs. Modular code design. Common errors to watch out for, as in jj2007's "tips, tricks and traps" - like eax can get blown away by a Windows call. This tutorial mentions ecx's volatility in loop instructions. That sort of thing is more important for beginners.

That's right and there are a lot of other precious sources, for example:

Gunther
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: hutch-- on September 28, 2016, 09:56:13 AM
 :biggrin:

And one day someone will actually read the Intel ABI (Application Binary Interface) and stop preaching nonsense about how you don't have to bother if you can get something to run on at least one version of Windows.
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: rrr314159 on September 28, 2016, 10:10:14 AM
Quote from: hutch-- on September 28, 2016, 09:56:13 AMAnd one day someone will actually read the Intel ABI (Application Binary Interface) and stop preaching nonsense about how you don't have to bother if you can get something to run on at least one version of Windows.

That's probably the same day pigs will fly.
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: hutch-- on September 28, 2016, 12:08:31 PM
 :biggrin:

> That's probably the same day pigs will fly.

That has been my experience.  :P

Why write system defined reliable code when you can cobble together garbage that crashes on other Windows versions.

A voice crying in the wilderness etc .....
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: Raistlin on October 04, 2016, 05:03:35 PM
I want to rant.....

I read the post and and got mad at the opening statements - saw the xchg thing and some other crap - and got madder. Then browsed the net and saw more of the same.

Why do they keep on telling people that assembly language should be used sparingly; and inline; and for small projects; and more....(CRAP)

People should know:
-----------------------
- Writing large projects as assembly applications are typically MUCH smaller & MUCH more efficient than the bloatware high-level languages spit out. This has real impacts
   especially in today's world of heterogeneous hardware that need to integrate for functionality.
- The claim is that high-level languages should only be used for high complexity abstracted & object orientated work. (Take that ! - you snobs)
- There is academic peer reviewed proof (see post: current assembly resources...) that handwritten assembly programming outperforms state of the art compilers always.
- Writing tutorials for assembly language should exclude DOS environments initially (my opinion & observation) - as it deters newbies... not sexy enough to grab their attention.
- Telling people it's difficult to learn and is error prone, has long debug times etc. as disadvantages or 'when not to use assembly' is just plain legacy. Visual IDE's anyone?
- My current project as some might know (something in the lines of grid computing - can't say much at present); would not be possible without assembly language, this must
   be true of other types of projects as well. If you can think it - you can do it - But only assembly provides the means.   
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: hutch-- on October 04, 2016, 07:41:27 PM
Funny story from long ago, when Iczelion and myself were hammering out the earliest versions of MASM32, we kept hearing how writing in assembler was illegal, immoral, fattening, rotted your sox and gave you zits, could not be written reliably, was impossible to debug and did not work any better. A year or so later all we heard was numb silence as missiles (properly written assembler software) went whizzing past them at one tenth the size. Slightly later Microsoft re-released ML.EXE and it has been one of the "boys toys" in VC/VS ever since.

I don't have any problems with high level languages, in places where you are shoveling chyte, anything will do and if you are not writing speed critical software, often good results can be produced by a high level language but when push comes to shove, if you want it to be powerful, fast and flexible, you write it in assembler. It has never been for the faint of heart, they should stick to server side scripting, JAVA or visual garbage generators.  :P
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: jj2007 on October 04, 2016, 08:56:54 PM
Quote from: Raistlin on October 04, 2016, 05:03:35 PMI want to rant...
Quote from: hutch-- on October 04, 2016, 07:41:27 PMassembler was illegal, immoral, fattening, rotted your sox and gave you zits

I fully support you, of course, also by demonstrating that projects in the +10k lines range can be done (A guide to the RichMasm editor (http://masm32.com/board/index.php?topic=5314.0)) :P

However, it's not that clear-cut:
Writing projects in VGGs is easy and produces, well, garbage.
Writing pure assembler is fun but produces, well, very small executables :biggrin:

The highest productivity comes, IMHO, with macros and a good library. Example:
  Dim My$()
  Let My$(1)=Input$("What's your hobby? ", "assembler programming")
  Let My$(0)="You entered ["+My$(1)+"]"
  Print My$(0)


Same as 44 lines of pure assembler:push 0                                                         ; ÚArg2 = 0
push 5                                                         ; ³Arg1 = 5
call MbArrayDim                                                ; ÀSkelMbEmpty.MbArrayDim
mov dword ptr [MbErrLine], 0B
push 1
push 5
call MbArrayGet
push offset ra_lbl2                                            ; ASCII "assembler programming"
push offset ra_lbl3                                            ; ASCII "What's your hobby? "
pushad
fxsave [MbXs]
mov eax, 4E4
push eax
push eax
call SetConsoleCP                                              ; Jump to kernel32.SetConsoleCP
call SetConsoleOutputCP                                        ; Jump to kernel32.SetConsoleOutputCP
fxrstor [MbXs]
popad
call MbInputStrP                                               ; ÀSkelMbEmpty.MbInputStrP
mov dword ptr [MbErrLine], 0B
push 7F
push 80000001
call MbPrint
mov dword ptr [MbErrLine], 0C
push 0
push 5
call MbArrayGet
mov dword ptr [MbErrLine], 0C
push 1
push 5
call MbArrayGet
mov dword ptr [MbErrLine], 0C
push offset MbLs1                                              ; ASCII "You entered ["
push 7F
push offset MbLs2
push 80000003
call MbPrint
mov dword ptr [MbErrLine], 0D
push 0
push 5
call MbArrayGet
push 7F
push 1
call MbPrint


Now, one interesting observation is that it would look only marginally more orderly in C/C++ 8)

Like Hutch with PowerBasic, I grew up with GfaBasic, and have written fairly big projects in that language (a mix of Basic and Pascal, I've been told). Not all Basic dialects are decent programming languages, many are crappy, and standardisation is lacking.

But some are damn good, PowerBasic for example. GfaBasic was top in the 16-bit era, but they failed to port it, that's why I had to do that (http://masm32.com/board/index.php?topic=94.0) ;-)

In the process of doing so in MASM, I also was more or less obliged to touch C - header files etc. Some here in the forum (mainly Erol) pushed me to look at Pelles C (http://forum.pellesc.de/index.php?action=unread), which is a decent programming environment. But overall, for somebody used to simple Basic, C/C++ is torture and a can of worms. It is more difficult than assembler, and the result is Bloat without the Power. Try a C equivalent to the code posted above...

Plus, launching that behemoth of Visual Studio gives me the creeps - in the time that it takes to start it, to create a new project and to "configure" it, I would have already coded the entire source in MasmBasic, in a single file instead of a dozen "modules" spread all over the place.

MasmBasic is my personal thing, but for those who prefer another syntax: Check out the \Masm32\help\ folder, in particular hlhelp.chm and masmlib.chm - as Hutch wrote above, the Masm32 library pushed assembly back on the scene of serious programming.

Of course, pure assembler is good for playing with instructions and learning to move values in registers and memory locations etc - the typical stuff they will teach in a university course on assembler. But for productive work, you must accept the use of macros. And just in case that you are one of those who believe that macros produce less efficient code: Post an example. One is enough 8)
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: HSE on October 05, 2016, 01:14:23 AM
Quote from: Raistlin on October 04, 2016, 05:03:35 PM
If you can think it - you can do it ... only assembly provides the means.
:t
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: RuiLoureiro on October 06, 2016, 01:23:28 AM
Quote from: hutch-- on September 27, 2016, 11:31:18 AM
With a quick scan, his reference material looks OK and much of it is just good programming practice but nothing beats the Intel manuals once you can get your head around them. I am always wary of any form of "politically correct" notions of how you write code and particularly with assembler code, architectural freedom is one of its greatest advantages. Others have written optimisation techniques, Agner Fog did very influential work as well as one of the Intel manuals but nothing beats the clock, design it, time it and keep going until the numbers don't get any lower.  :biggrin:

After that, then try it on different processor versions and learn the joys of average performance across a variety of different processors.  :P

XCHG was slow on a single core PIV, it never got any better on multicore hardware. Try and forget old DOS style instructions, they were super heros on a 286, anything committed to processor microcode is there for backwards compatibility reasons.
YES ! Very well ! :t
:icon14:
EDIT: i like this sentence: «visual garbage generator»!  :icon_cool:
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: RuiLoureiro on October 06, 2016, 01:29:31 AM
Quote from: Gunther on September 27, 2016, 08:14:16 PM
Quote from: Zen on September 27, 2016, 05:57:13 AM
20 Basic Practices in Assembly Language Programming, CodeProject (http://www.codeproject.com/Articles/1116188/Basic-Practices-in-Assembly-Language-Programming), by Zuoliu Ding.

The article is good for novices. But there are other sources, too.

Quote from: hutch-- on September 27, 2016, 11:31:18 AM
... but nothing beats the clock, design it, time it and keep going until the numbers don't get any lower.  :biggrin:

That's the right approach.

Gunther
Hi Gunther,
                  How are you ?
Nice to see you here :t
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: RuiLoureiro on October 06, 2016, 02:01:23 AM
Hi all
      I want to add this:
      If we write a procedure that uses a local stack buffer of length N and it may be used
      to copy from/to another using movdqa/movdqu instructions and registers xmm, it
      is fast if the starting address is aligned by 16. I don't know if all this type of
      buffers are created aligned by 16 or not and i never tested it (i align it by 16)
      What do you have to say ?
      More, it seems that a procedure that uses local variables, when we have the carry clear
      and call that procedure and it starts by pushfd and exits with popfd, the next state of
      carry flag may be carry set. I don´t know why. 

For instance

ProcA                  proc           pStrBuf:DWORD, pSubType:DWORD

                            LOCAL       BufferB[TOTALofSTACKBUFFER1024]:BYTE
                            LOCAL       BufferC[TOTALofSTACKBUFFER512]:BYTE
                            LOCAL       BufferD[TOTALofSTACKBUFFER512]:BYTE

                            push        ebx
                            push        esi
                            push        edi
            ;
            ; something
            ;
                            pop          edi
                            pop          esi
                            pop          ebx
                            ret
ProcA                   endp
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: nidud on October 06, 2016, 03:46:27 AM
deleted
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: Gunther on October 06, 2016, 04:30:56 AM
Quote from: RuiLoureiro on October 06, 2016, 01:29:31 AM
Hi Gunther,
                  How are you ?
Nice to see you here :t

All things considered, I'm doing just fine. And how are you?

Quote from: RuiLoureiro on October 06, 2016, 02:01:23 AM
      More, it seems that a procedure that uses local variables, when we have the carry clear
      and call that procedure and it starts by pushfd and exits with popfd, the next state of
      carry flag may be carry set. I don´t know why. 

I agree with nidud: it's the prologue.

Gunther
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: RuiLoureiro on October 06, 2016, 08:51:56 AM
Quote from: nidud on October 06, 2016, 03:46:27 AM
Quote from: RuiLoureiro on October 06, 2016, 02:01:23 AM
      More, it seems that a procedure that uses local variables, when we have the carry clear
      and call that procedure and it starts by pushfd and exits with popfd, the next state of
      carry flag may be carry set. I don´t know why. 

I will assume it's the prologue code:

local   x
*   push   ebp
*   mov   ebp,esp
*   sub   esp,4   ; <-- changes the flags
   pushfd

Hi nidud,
          I think so. Thanks  :t
          Now, all my TestProcs that i put after «_exit» doesnt use
          any local variables or it uses global variables.
         
Example: (note:all Test Procs start with pushfd and pushad
                 and exit with popad and popfd and ret)
Quote
ProcA                proc          pStrBuf:DWORD, pSubType:DWORD
                       LOCAL       BufferB[TOTALofSTACKBUFFER1024]:BYTE
                       LOCAL       BufferC[TOTALofSTACKBUFFER512]:BYTE
                       ...
                       push        ebx
                       push        esi
                       push        edi
                       ;-------------------------------------------
                       ;   Align by 16 BufferB and put the pointer
                       ;     into edi and ebx for BufferC.
                       ;-------------------------------------------
                       ALIGNLOCALPOINTERedi  BufferB, LENofSTACKBUFFER1024
                       ALIGNLOCALPOINTERebx  BufferC, LENofSTACKBUFFER512                       
                       ...
                       mov             esi, pStrBuf
                       ...
       ;
       ; something
       ;       
           _isdone:    clc          <<<<<<<--------------------
                       ;----------------------------------------
                       ; If it exits with clc, it did the task
                       ; If it exits with stc, there is an error
                       ;----------------------------------------
             _exit:   
                       ;----------------------------------------
                       ; This test proc starts showing the carry flag:
                       ; If clear -> we get: the carry is CLEAR
                       ;    NOT   ->       : the carry is SET
                       ;----------------------------------------
                       invoke       SomeTestProcX, A, B...
                       or
                       call         SomeTestProcX
                       ;------------------------------------------
                       ; If SomeTestProcX uses local variables
                       ; we get: the carry is SET and we know
                       ; that ProcA exits in the label «_isdone».
                       ;------------------------------------------
                       pop          edi
                       pop          esi
                       pop          ebx
                       ret
      _erro273:    ...
                       stc
                       jc           short _exit                       
ProcA                endp                           
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: RuiLoureiro on October 06, 2016, 09:15:53 AM
Quote from: Gunther on October 06, 2016, 04:30:56 AM
Quote from: RuiLoureiro on October 06, 2016, 01:29:31 AM
Hi Gunther,
                  How are you ?
Nice to see you here :t

All things considered, I'm doing just fine. And how are you?

Quote from: RuiLoureiro on October 06, 2016, 02:01:23 AM
      More, it seems that a procedure that uses local variables, when we have the carry clear
      and call that procedure and it starts by pushfd and exits with popfd, the next state of
      carry flag may be carry set. I don´t know why. 

I agree with nidud: it's the prologue.

Gunther
Hello Gunther,
   i'm fine but older. It's a nature problem !
There is no solution, even using assembly laguage, Gunther !
See you and Good Luck. :t
:icon14:
Rui
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: GuruSR on October 06, 2016, 11:59:14 AM
Quote from: Gunther on September 27, 2016, 08:14:16 PM
Quote from: Zen on September 27, 2016, 05:57:13 AM
20 Basic Practices in Assembly Language Programming, CodeProject (http://www.codeproject.com/Articles/1116188/Basic-Practices-in-Assembly-Language-Programming), by Zuoliu Ding.

The article is good for novices. But there are other sources, too.

Quote from: hutch-- on September 27, 2016, 11:31:18 AM
... but nothing beats the clock, design it, time it and keep going until the numbers don't get any lower.  :biggrin:

That's the right approach.
I actually got into a debate on one site (related to a game) with a C programmer who stated that nobody clock counts, ever.

I've written an Jump Man Jr. clone on a Vic-20 (hell if I didn't count cycles) that did animated "sprite like" movement with collision detection on the pixel level (and I used a raw memory editor that let me write code directly in ram, damn sure I counted).  Wrote an addition of the Vic-20 and a robotic arm, so it would be 1/10th of a degree accurate in all movements with it (infrared sensors), that one I used an "IDE" of sorts and wrote that extension, wrote a "to be rom" for a DJ control for lighting, had to be able to read the sound and react to it with light patterns, that I counted code, because the rom was only so big (2k if I recall) and he wanted patterns to be programmable.

Anyone who isn't counting the clock for performance is either not worried about it, or another lazy C programmer...  Must be working for Microsoft.  <VENT>"Hey Microsoft, fix the Windows 3.1 bug in Windows 10 will you?!  I hate having to deal with the print spool causing all the printers to vanish, like FIX that bug already."</VENT>

One of these years, I'll get around to using macros in the IDE, maybe...  Too old school, do it all myself, at least there's an IDE now, not like raw editing memory.

GuruSR.
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: Gunther on October 07, 2016, 01:05:59 AM
Hi GuruSR,

Quote from: GuruSR on October 06, 2016, 11:59:14 AM
I actually got into a debate on one site (related to a game) with a C programmer who stated that nobody clock counts, ever.

This buddy has no idea. That's for sure.

Quote from: GuruSR on October 06, 2016, 11:59:14 AM
I've written an Jump Man Jr. clone on a Vic-20 (hell if I didn't count cycles) that did animated "sprite like" movement with collision detection on the pixel level (and I used a raw memory editor that let me write code directly in ram, damn sure I counted).  Wrote an addition of the Vic-20 and a robotic arm, so it would be 1/10th of a degree accurate in all movements with it (infrared sensors), that one I used an "IDE" of sorts and wrote that extension, wrote a "to be rom" for a DJ control for lighting, had to be able to read the sound and react to it with light patterns, that I counted code, because the rom was only so big (2k if I recall) and he wanted patterns to be programmable.

That sounds impressive. Canada must be a good area for assembly language programmers.  8)

Gunther
Title: Re: 20 Basic Practices in Assembly Language Programming
Post by: GuruSR on October 07, 2016, 03:15:33 PM
Quote from: Gunther on October 07, 2016, 01:05:59 AM
This buddy has no idea. That's for sure.

Long before C programming was even a thing, I was writing code on punch cards (and no, never crashed that one, trust me, you knew it when that happened, shook the floor), then next wrote a logic circuit on paper and created the actual live circuit in electronics.  So when someone tells me nobody counts cycles, I laugh as I know that hand held game device game programmers have no choice, because his answer was to throw more horse power (faster CPU) at it.   :dazzled:  And my comment to him was (since it was an XBox360/PC game), that it's a nice idea for the PC, but what about those people with the XBox 360 version, both were written using the same base code (as was a good means of reducing production costs).  He still said that they didn't count cycles for the game and it just "worked fine" as it was...  I was so tempted to ask him to write a mini game that couldn't be any larger than 8k in size (I didn't, because I know PrintF is a lot larger than that).

Quote from: Gunther on October 07, 2016, 01:05:59 AM
That sounds impressive. Canada must be a good area for assembly language programmers.  8)

Thanks, yes, my youth was mostly coding, pretty much, got a recognition for writing an assembler 'simulation' program so people learning assembler in the years following would use my 'simulation' to watch how the process worked.  That was basically what I did in that course since I finished the course in a week (helped learning assembler over the summer with my own Vic-20, but the machines at the school were Commodore Pet's, wow, nostalgia).  Got asked why I was able to finish the projects so fast, well, the year prior, I was the only guy in a typing course.  I figured, I need to learn to type to program faster, so I took the course and well, now I'm roughly 60-70wpm.  The following year, I heard a few of the guys joined a course just to get better too, some of the girls in that course were "upset at me for suggesting it"...  Oh no, Drama at School, film at 11!

GuruSR.