The MASM Forum

General => The Campus => Topic started by: LordAdef on January 22, 2017, 09:42:24 AM

Title: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 22, 2017, 09:42:24 AM
Hello everyone,

Please allow me to introduce myself and tell why and how I am here today.

.me
  I´m Alex (LordAdef is an old avatar I can´t get rid of...it´s my Macro  :greensml:). I´m Brazilian and am 45. I am a music composer and music producer. As everyone around my age, I started programming BASIC, qBASIC etc.... Afterwards I had some quick experience with C. I quit programming when classical music came in and took all my time. Then it came Bachelor Degree and Masters Degree. After things got quieter, the addiction hit me back and I made several programs in a language called Lingo (native of the former Macromedia Director). It was crap, but I had some fun.

So, as an introduction, I´m not a professional and not a student under supervision, I´m only brave :D

.why?
Recently, addiction hit me again... I need to bloody program!! I need to bloody program!!
Options for serious stuff, not toys, were down to:
  C++  -> absolutely not
  C or Assembly  -> ?????????

  C came out being the one... thousands of links tutorials, videos in youtube and so forth..
  Assembly was once again left behind

.Then
  VStudio is free, soon I finished a quite nice game prototype all in pure C, using the SDL libs. Great!!!
  Meanwhile, I couldn´t resist and was reading all I could find about asm on the internet. Believe me, I know all the tuts in youtube. I read a couple of books either.

.aFeedback
  Asm is not "Not for the faint of heart" (now a legendary line for me)... finding your way around it today without supervision IS...

  I would love if some of you top guys could someday write a "Get started"... Assembly deserve a complete and up to date one. For me was like coming into a jungle... it still is!!!


.foundYou
  So I decided for MASM. It was an easy choice really. I didn´t know (as most of us noobs) the HLL capabilities. And them I MASM32.
  At this point I already know most of you by name(Hutch, Gunther, jj, etc..)! I´ve been reading this forum for a long long time. GREAT PEOPLE!!!
  Hutch, I think you are a legend! your work and efforts brought me to Assembly

.Enough
  I could be writing nonstop about this Saga for ages.
  I don´t know anything, I´m just starting. I won´t fill the forum with question after question (I read the rules  :eusa_dance:). But if anyone could provide me with some help, this would be great.

Thank you for MASM32 existence

ps: edited typos


 
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on January 22, 2017, 10:18:15 AM
Welcome to the Forum, Alex - you are at the right place here :icon14:
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on January 22, 2017, 01:36:37 PM
Hi Alex,

Good to see you here. We will lead you astray with the intent of seeing you produce small fast code. The line "not for the faint of heart" is in fact true, assembler programming is hard to learn, brutally intolerant and will bite you on the arse for the slightest mistake but it teaches you to do things the right way the first time, don't take crappy short cuts and to write reliable code. It can be a rough ride at first but once you get it, its a ton of fun and you get high quality results from it.
Title: Re: "Hello masm32", not a BOT, new member
Post by: Magnum on January 23, 2017, 03:05:46 PM
Welcome Alex.

Andy
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 23, 2017, 09:34:46 PM
Quote from: jj2007 on January 22, 2017, 10:18:15 AM
Welcome to the Forum, Alex - you are at the right place here :icon14:

Thank you JJ! It took me a while to join. By the way, I downloaded MasmBasic too. In fact, I followed your tips and tricks page when downloaded masm32!
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 23, 2017, 09:48:59 PM
Quote from: hutch-- on January 22, 2017, 01:36:37 PM
Hi Alex,

Good to see you here. We will lead you astray with the intent of seeing you produce small fast code. The line "not for the faint of heart" is in fact true, assembler programming is hard to learn, brutally intolerant and will bite you on the arse for the slightest mistake but it teaches you to do things the right way the first time, don't take crappy short cuts and to write reliable code. It can be a rough ride at first but once you get it, its a ton of fun and you get high quality results from it.

I´m feeling at home already by the warm welcome!
I guess we find the right place when you find people with common interests. I could be doing my C thing and make my life easier. But you know.... Assembly looks so more obvious to me... and I always forget the bloody semicolons at the end of lines... Assembly don`t have them  :greenclp:

So I know the homework... I bought the new Rolling Stones album and am ready to crack on the masm32 help files.

I also am reading the whole Campus forum. It´s something the Newbies should do before asking the same questions. It´s greatly informative since you guys already answered many of the same questions.

I installed masm32 in a different computer from the VStudio one. It´s a clean start. I´m fine with no syntax highlighting, but still need to get used not to have the integrated debugger as in VS. For that I downloaded the Olly one as JJ suggested
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 23, 2017, 09:53:06 PM
Quote from: Magnum on January 23, 2017, 03:05:46 PM
Welcome Alex.

Andy

Thanks Andy!
For how long do we have to keep answering these verification questions?
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on January 23, 2017, 10:44:16 PM
not for long, its only to deter spammers.
Title: Re: "Hello masm32", not a BOT, new member
Post by: mineiro on January 24, 2017, 02:00:38 AM
hello LordAdef, welcome irmão
[<o>]
Title: Re: "Hello masm32", not a BOT, new member
Post by: AssemblyChallenge on January 25, 2017, 08:34:21 AM
Hi, and welcome to the forum :biggrin:

If you are just setting up your workshop, most people here will not recommend VS because it's too big and bloated.

Hardcore assemblers go with something simpler like Top Gun editor (included in MASM32). As someone who already tried Radasm and Winasm, I gave my vote to EasyCode if you want 32/64 bits, WYSIWYG and syntax highlighting in a breeze; EC's help file is worth its weight in gold by itself. :lol:

Happy coding :t
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 25, 2017, 06:57:02 PM
Quote from: mineiro on January 24, 2017, 02:00:38 AM
hello LordAdef, welcome irmão
[<o>]

Hey Mineiro, I already knew there was a fellow country man here. Obviously, by your name and the Raul Seixas´ quote you use in your posts  :t

Thanks for stopping by and say hello.

I´m from Rio de Janeiro, and I guess you are in Minas, right?

Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 25, 2017, 07:04:15 PM
Quote from: AssemblyChallenge on January 25, 2017, 08:34:21 AM
Hi, and welcome to the forum :biggrin:

If you are just setting up your workshop, most people here will not recommend VS because it's too big and bloated.

Hardcore assemblers go with something simpler like Top Gun editor (included in MASM32). As someone who already tried Radasm and Winasm, I gave my vote to EasyCode if you want 32/64 bits, WYSIWYG and syntax highlighting in a breeze; EC's help file is worth its weight in gold by itself. :lol:

Happy coding :t

Hi AssemblyChallenge, thanks for the advises. I´m aware of the VS thing. In fact, I installed masm32 in a different computer (faaaaar away from VS). To be quite honest, I still miss the integrated debugger of VS, but I´m getting used to the new tools (and getting to know then)

I´m playing with the qEditor and JJ´s RichMasm. But today I downloaded EasyCode too.

I´m too impressed with how friendly this community is! I´m spending a great deal of time skinning through old threads and checking out. Amazing.

Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 26, 2017, 11:19:40 AM
Guys,

qEditor, demo 5 (numbers.asm):

It doesn´t compile. I´m pretty sure it´s not recognizing the "include \masm32\macros\macros.asm".
I commented all the includes and included the masm32rt.inc instead and all worked fine
Quoteinclude \masm32\include\masm32rt.inc
   
comment #
    include \masm32\include\windows.inc     ; always first
    include \masm32\macros\macros.asm       ; MASM support macros

  ; -----------------------------------------------------------------
  ; include files that have MASM format prototypes for function calls
  ; -----------------------------------------------------------------
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc


  ; ------------------------------------------------
  ; Library files that have definitions for function
  ; exports and tested reliable prebuilt code.
  ; ------------------------------------------------
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
#

I´d like to know what´s happening
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on January 26, 2017, 11:32:50 AM
Quote from: LordAdef on January 26, 2017, 11:19:40 AM
qEditor, demo 5 (numbers.asm):

It doesn´t compile. I´m pretty sure it´s not recognizing the "include \masm32\macros\macros.asm".
...
I´d like to know what´s happening

So you get an assembler error. Where did you find numbers.asm? Which error, which line? Same error in RichMasm?
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on January 26, 2017, 11:56:38 AM
The original file was missing the include and library for MSVCRT. Including the "masm32rt.inc" file solves the problem as it does contain msvcrt. The original file was written in 2004 and something has changed since.

If you wanted to use the older form in the original, it would look like this.

  ; -----------------------------------------------------------------
  ; include files that have MASM format prototypes for function calls
  ; -----------------------------------------------------------------
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\msvcrt.inc

  ; ------------------------------------------------
  ; Library files that have definitions for function
  ; exports and tested reliable prebuilt code.
  ; ------------------------------------------------
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\msvcrt.lib
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 26, 2017, 12:03:12 PM
JJ:
QuoteSo you get an assembler error. Where did you find numbers.asm? Which error, which line? Same error in RichMasm?

Numbers.asm is the demo 5 in masm32 tutorials. Hutch already pin pointed the issue. masm32rt is the way to go!
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 26, 2017, 12:07:30 PM
Hutch
QuoteIf you wanted to use the older form in the original, it would look like this.

Thanks! I´m fine with the modern way. I bloody love masm32rt.inc!!!!

Sorry to bother you guys!
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on January 26, 2017, 07:50:51 PM
Quote from: LordAdef on January 26, 2017, 12:03:12 PM
Numbers.asm is the demo 5 in masm32 tutorials.

Glad you solved it :t

Tmp_File.asm(73) : Error A2159: INVOKE requires prototype for procedure
sval(2)[macros.asm]

      sval MACRO lpstring
        IFNDEF __UNICODE__
          invoke crt_atol,reparg(lpstring)
        ELSE
          invoke crt__wtol,reparg(lpstring)
        ENDIF
        EXITM <eax>
      ENDM
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 30, 2017, 07:04:59 PM
Hi guys,

So.....I´ve been doing my homework... and I wrote this small (and useless) program. My first!

I wanted to do something very simple, so that I could accomplish and show it to you gurus.

It DOES work!!

Your comments will be invaluable, from every point of view... Not just in ways to optimize it but also how it´s commented and presented.

It was all coded in qEditor and I didn´t need debugging for this one.

Please, be kind, I´m actually quite proud of my small little beast  :biggrin:

Any comment will be of great help.
Cheers

Alex
ps: .zip file attached
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on January 30, 2017, 08:09:08 PM
Hi Alex,
Nice effect, it works like a charm :t

Little suggestions:
    mov esi, offset Ln1
 
    ; xor eax, eax ; will be immediately overwritten
    mov eax, SIZEOF Ln1 ; no Ssize needed                  ;Get item based on LoopC index
    mul LoopC
    add esi, eax                    ;ADD size => next line

    print esi, 13, 10               ;PRINT next

    inc LoopC                       ;increment Loop
    ; xor edx, edx                    ;Get =>LoopC mod LINES
    mov eax, LoopC
    cdq ; sets edx to zero but is one byte shorter than xor edx, edx


For assigning small numbers (-128 ... +127) to registers, there is the m2m macro:
m2m eax, 123
mov eax, 123


Same result but m2m is 2 bytes shorter. Do not use it in a speed-critical innermost loop (i.e. one with >1Mio iterations).
m2m means "memory to memory", it does a
  push 123
  pop eax
which is not exactly mem to mem but it works :P

You can eliminate one jump, but attention to the logic:
    .ELSE
        inc LineC


We all love eliminating jumps 8)
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 30, 2017, 09:39:01 PM
Thank you so much JJ!!!!

I made all the changes, and also managed to eliminate the jump:

Quote.IF LineC==LINES                ;AFTER lines are printed
        inc LineOffSet              ;increment LineOffSet and make it modular
        xor edx, edx
        mov eax, LineOffSet
        mov ebx, LINES
        div ebx
        mov LoopC, edx              ;add LineOffSet to LoopC, so to increment the starting line
       
        mov LineC, 0                ;Set to 0 instead of 1, to eliminate the jump
        loc 0,0                     ;Return console cursor to line 0
    .ENDIF
   
    inc LineC   

I´m thinking that maybe I could eliminate LineC. I´m using LoopC for modulus and LineC to keep track of my Lines. Maybe, I could increment a LOCAL variable (or a safe register) based on LoopC and throw LineC away. Not sure if it will take any considerable load though.

Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 30, 2017, 09:50:05 PM
Yes, I eliminated LineC and am using edi for the job. I guess I get some boost from this.

Any place you think I should use m2m in the code?
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on January 30, 2017, 11:11:03 PM
Quote from: LordAdef on January 30, 2017, 09:50:05 PMAny place you think I should use m2m in the code?

m2m eax, SIZEOF Ln1

But really, this is just a habit of old assembler programmers who like optimising ;)

Other example:
         and LineC, 0                ;reset LineC
3 bytes shorter.

(some may argue that this is a) slower and b) useless, because there is more than enough RAM around. Truth is that it's no good in a tight innermost loop; but anywhere else it is good, because the instruction cache is very small, and it may make a difference if a whole loop fits into that cache because you saved a byte here and there)
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on January 31, 2017, 10:24:48 AM
Thanks JJ, ALL comments well noted and learned!
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on January 31, 2017, 10:47:46 AM
Just a comment on the macro "m2m". The rough distinction is you use m2m in high level code to make it more compact and easier to read. In any code that is time critical it is faster to use a register.

mov reg, memory2
mov memory1, reg

Its common from the 16 bit DOS era for byte pinching here and there but we have very different hardware and OS conditions these days and you generally chase speed before size as the size difference is trivial where the speed difference is worth having. Speed comes from picking the right algorithm, coding the algorithm carefully with the right choice of instructions, minimising the number of branches and keeping memory access to a minimum (memory is slow in comparison to registers).

This stuff comes with practice and the CLOCK, when speed matters, your only real friend is the CLOCK. Its like in motor racing, when the flag drops the bullshit stops.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 01, 2017, 07:25:19 PM
Thanks Hutch! I see what you and JJ mean. I incorporated "m2m" and "and" in my codes. I imagine these principles get more valid when you have larger codes, when saving bytes here and there will count (as pointed out by JJ).
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 01, 2017, 07:44:37 PM
My first prog was reading the lines as variables from the data section. I thought it would be nice if it read the data from file.

So I coded my prog2. This time I made a procedure, since I intend to integrate this LoadFile proc into the other code.
I used m2m and AND, following JJ´s observation.

It was a nice exercise. I had to deal with things I haven´t touched before.
I am also learning that Assembly is a severe father! It took me half an hour to realize I had written "map1.text" instead of "map1.txt". I felt a complete idiot, since I almost got nuts trying to understand what was wrong...

I sending to the proc an offset of my string (the file name).
I´m using:
QuotepLoad proc, string:LPSTR

I tried DWORD and it worked too. I found about LPSTR searching our forum, and it was the recommended one. Would you clarify me on this?

Once again, thank you for all this support.
Alex

ps: I may not touch any C for the next decade.... Assembly is beautiful :eusa_boohoo:
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 01, 2017, 07:51:24 PM
Quote from: hutch-- on January 31, 2017, 10:47:46 AMIn any code that is time critical it is faster to use a register ... your only real friend is the CLOCK

Correct. Just to illustrate this:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  loopcount=100000000
  PrintCpu 0
  Print Str$("\nTimings for %i loops:\n", loopcount)
  REPEAT 5
      NanoTimer()
      mov ecx, loopcount
      .Repeat
            mov eax, 127
            dec ecx
      .Until Zero?
      Print Str$("%i ms for mov\n", NanoTimer(ms))
      NanoTimer()
      mov ecx, loopcount
      .Repeat
            m2m eax, 127
            dec ecx
      .Until Zero?
      Print Str$("%i ms for m2m\n\n", NanoTimer(ms))
  ENDM
EndOfCode


Results:Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz

Timings for 100000000 loops:
35 ms for mov
69 ms for m2m

34 ms for mov
69 ms for m2m

35 ms for mov
103 ms for m2m

35 ms for mov
70 ms for m2m

34 ms for mov
68 ms for m2m


In short: You need ONE-HUNDRED MILLION iterations to demonstrate that m2m is "slower" than mov.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 01, 2017, 07:56:35 PM
QuoteIn short: You need ONE-HUNDRED MILLION iterations to demonstrate that m2m is "slower" than mov

Incredible! Noted
Also you just taught me how to profile my code... I was missing this JJ. This may be my entry point to masmBasic
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 01, 2017, 08:01:14 PM
Quote from: LordAdef on February 01, 2017, 07:44:37 PMI found about LPSTR searching our forum, and it was the recommended one. Would you clarify me on this?

Windows.inc: LPSTR typedef DWORD

It's exactly the same type. 90% of all code in assembler deals with dwords, the rest being REAL4/8/10, byte and word variables.

Now what is right here? Raise the question and find yourself in an ideological war between the old "hey, it's 4 bytes, isn't it?" fraction and those who come from C/C++ and see their world crumbling if you "mistype" LPSTR as DWORD :P

Btw if there is a real problem, the assembler will shout at you, at least in the 32-bit world. So don't worry.

Re LoadFile: Works like a charm, well done :t

You over-optimise a little bit, though. Once your code is running, it's always nice to see it through the eyes of a debugger...
pLoad proc, string:LPSTR       ;=============== Load, Parse file & fill array ========
    int 3                                       ;make Olly stop here when hitting F9
    and ebx,0                                   ;loop
    xor ebx, ebx                                ;shorter way of zeroing a register
    m2m esi, InputFile(string)                  ;Source file (ecx ret. size)         
    m2m edi, offset Map                         ;Destination
    mov edi, offset Map                         ;shorter - offsets are big numbers ;-)
   @@:
    m2m ecx, cWidth                             ;shorter, cWidth is a small number
    mov ecx, cWidth                             ;lenght of line
    rep movsb                                   ;copy
    inc edi                                     ;Skips 0s
    inc ebx                                     ;loop
    cmp ebx, cHeight
    jb @B
    free esi                                    ;closes it
    ret
pLoad endp



00401032        ³.  CC              int3
00401033        ³.  83E3 00         and ebx, 00000000
00401036        ³.  33DB            xor ebx, ebx
00401038        ³.  68 14224000     push offset 00402214           ; ÚArg3 = LoadFile.402214
0040103D        ³.  68 10224000     push offset 00402210           ; ³Arg2 = LoadFile.402210
00401042        ³.  FF75 08         push dword ptr [ebp+8]         ; ³Arg1 => [Arg1]
00401045        ³.  E8 C6000000     call 00401110                  ; ÀLoadFile.00401110
0040104A        ³.  8B0D 14224000   mov ecx, [402214]
00401050        ³.  A1 10224000     mov eax, [402210]
00401055        ³.  50              push eax                       ; m2m esi, InputFile(string)
00401056        ³.  5E              pop esi
00401057        ³.  68 00204000     push offset 00402000
0040105C        ³.  5F              pop edi
0040105D        ³.  BF 00204000     mov edi, offset 00402000
00401062        ³>  6A 0A           Úpush 0A
00401064        ³.  59              ³pop ecx
00401065        ³.  B9 0A000000     ³mov ecx, 0A
0040106A        ³.  F3:A4           ³rep movsb


Note, for example, that m2m esi, InputFile(string) results in a push eax, pop esi sequence; mov eax, esi has the same size, so no need to optimise here. In fact, the only valid cases for m2m are 1. memory-to-memory transfers between variables (that's why the macro was written) and 2. mov reg32, small integer (-128...+127).

A hard-core optimiser, btw, would save one byte by using xchg InputFile(string), esi:
00401045        ³.  E8 C6000000     call 00401110                  ; ÀLoadFile.00401110, read_disk_file
0040104A        ³.  8B0D 14224000   mov ecx, [402214]
00401050        ³.  A1 10224000     mov eax, [402210]
00401055        ³.  96              xchg eax, esi                  ; m2m esi, InputFile(string)


Don't make this a habit, though: You risk losing a lot of time chasing single bytes instead of concentrating on good code.

For better understand the disassembly, here an excerpt from \masm32\macros\macros.asm:

      InputFileA MACRO lpFile
...
        invoke read_disk_file,reparg(lpFile),
               ADDR ipf@__@mem@__@PtrA,
               ADDR ipf@__file__@lenA

        mov ecx, ipf@__file__@lenA   ;; file length returned in ECX
        mov eax, ipf@__@mem@__@PtrA  ;; address of memory returned in EAX
        EXITM <eax>
      ENDM
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 02, 2017, 02:02:27 PM
Thanks,

I´ll have a closer and careful look at the debugger.

QuoteDon't make this a habit, though: You risk losing a lot of time chasing single bytes instead of concentrating on good code.
Ok. But it´s always a good habit to learn from the beginning I think. The most precious thing I´m learning from you is the "mindset". If you don´t learn this, one will never become a good Assembly programmer.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 02, 2017, 02:46:42 PM
Update, prog3


Prog3, ScrollingFromFile, uses 2 procedures: pLoad (my loading code from prog2) and pConsoleEngine (adapted from my prog1, it generates the scrolling effect on the console)

1. It loads the file, parse it and fills the array.
2. I put all the engine code into the procedure and made its variables as LOCALS, to encapsulate a bit (right design choice?)
3. I turned all constants into High Caps to be more consistent
4. Made the changes based on JJ´s comments
5. The lenght (cWIDTH) and number of lines (cHEIGHT) are still hard coded. I might work on this next, although my array declaration asks for constants:

   
Quote.const
    cWIDTH  EQU    20                           ;num of Chars in a line
    cHEIGHT EQU    60                           ;num of Lines 

.data
    Map        db  cHEIGHT  dup(cWIDTH dup(?),0)   ;Main array, adds 0 for termination
    Filename   db  "Map1.txt",0
4. When running the prog, we need to manually adjust the size of the console window to fit the current 60 lines. I didn´t bothered to search about this for now
5. Last but not least, I made a small Homage to JJ in the scrolling text :greenclp:

I might soon be porting this onto a Windows frame.

Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 02, 2017, 03:12:24 PM
There is a context for how and why some of the older fellas still do some things the way it was done over 25 years ago. With pre-486 processors (1990) you actually DID count cycles and with very slow 8088 and slightly later hardware, packing code into smaller layouts by instruction choice was a viable form of optimisation for writing memory image COM files in MS-DOS. The problem was that this changed with the 486DX which introduced the concept of a pipeline where the action switched to "scheduling" instructions through that pipeline in the most efficient order.

It also entailed abandoning some of the old instructions because while they still worked, the internal guts of the processors ran faster if you stuck to simpler preferred instruction set that Intel published. Packing instructions in the right order meant the processor did not have to stop and wait for a result which caused a stall and this became more important with multiple pipeline later processors. Some of this varied with different processors but the general direction from the 486 era onwards was to use simpler instructions in the right order, minimising branching and reducing the number of memory operations.

You can pick up bad habits like using out of date instructions (xchg, movsb/w/d/q and stosb/w/d/q without the REP prefix) and various others but it will come at the price of producing sub standard code that is often not as fast as junky high level code. You chase reduced instruction counts where you can by removing redundancies in your code but do not fall for just chasing code sized reduction as it does not produce useful results and often slows your code down.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 02, 2017, 09:04:23 PM
Quote from: hutch-- on February 02, 2017, 03:12:24 PMYou can pick up bad habits like using out of date instructions (xchg, movsb/w/d/q and stosb/w/d/q without the REP prefix)

Nothing of what Hutch writes is entirely wrong, but the context matters a lot. Inside a tight loop that runs a Million times, one should indeed be careful. In all other cases, xchg eax, reg32 saves a byte at no additional cost, and stosd is a wonderful instruction for storing a bunch of handles into their global variables. And there are numerous other examples where old instructions can be the right ones.

There are also the incredibly old inc and dec instructions, which trigger every now and then an exchange of religious views on the speed difference to add and sub, see here (http://masm32.com/board/index.php?topic=5900.0) for a recent example, or here (http://www.masmforum.com/board/index.php?topic=4662.msg34741#msg34741) for a less recent one (why is "add" faster than "inc", April 2006).

If you want to see super-fast super-modern "junky high level code" in action, install Visual Studio Community (https://www.google.com/search?num=20&newwindow=1&safe=off&site=&source=hp&q=Visual+Studio+Community+slow). The good news, it's free, but warning, your hardware is probably too old for such modern code, and it may take a while until you see the editor in front of you 8)
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 02, 2017, 10:43:02 PM
 :biggrin:

And when you add up all of the size reductions gained by picking old slow instructions, it still does not add one 512 byte section to an executable. Start down the slippery slope of writing garbage and you will end up with garbage.  :P
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 03, 2017, 02:54:05 AM
Quote from: hutch-- on February 02, 2017, 10:43:02 PMAnd when you add up all of the size reductions gained by picking old slow instructions

These instructions are old, but they don't slow down your code as long as you don't do really stupid things like squeezing them into a tight loop. On the contrary, every saved byte that does not end up in the instruction cache may indeed make your code faster.
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 03, 2017, 06:42:04 AM
 :biggrin:

> may indeed make your code faster.

This is indeed a big IF when code cache performance is easily testable. Loop unrolling is a perfect mechanism to see where the performance limit is. Keep increasing the level of unrolling until the code goes not faster then keep unrolling the loop code until it gets slower and you will find the cache limit of the particular processor you are using. Test it across a range of hardware and you will start to get averages and the code you put into production will hit somewhere in the middle of cache performance.

The assumption that code sized effects are cumulative across an entire application is unsound, it is always local to where the code occurs. With modern hardware, close range code size almost exclusively does not matter where instruction choice will bite you on that arse if you use old DOS era junk. Develop the habit of tolerating garbage to save a few bytes here and there and you will end up producing garbage.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 03, 2017, 08:02:58 AM
REPEAT 1000
 
Quote from: jj2007 on February 03, 2017, 02:54:05 AMThese instructions are old, but they don't slow down your code as long as you don't do really stupid things like squeezing them into a tight loop.
Quote from: hutch-- on February 03, 2017, 06:42:04 AMDevelop the habit of tolerating garbage to save a few bytes here and there and you will end up producing garbage.

ENDM
Title: Re: "Hello masm32", not a BOT, new member
Post by: TWell on February 03, 2017, 08:23:16 AM
I think that people use assembler to optimize code.

Those who want to generate garbage to waste CPU resources, there is already Java for that.
Just couple lines of code and lot of memory and CPU cycles wasted.
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 03, 2017, 09:02:10 AM
 :biggrin:

> REPEAT 1000

Repetition does not make substandard code work any better. Write garbage, get garbage.  :P

Tim,

You can write poor code in any language, assembler is certainly not immune from producing slow sloppy code as many have found out.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 03, 2017, 10:40:55 AM
Quote from: hutch-- on February 03, 2017, 09:02:10 AMWrite garbage, get garbage.

Did I ever insult you, Hutch?
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 03, 2017, 12:28:34 PM
 :biggrin:

> Did I ever insult you, Hutch?

Regularly but its useful for folks learning to understand that there is a wide variety of opinion in coding techniques and the only one that matters is their own.  :P
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 04, 2017, 08:24:51 AM
Update: prog4, the scrolling ported to windows.

I use Iczelion´s code for the Window and changed it to my taste.
Run it and move you mouse over the window to trigger the scroll.

The rendering code is within the Window message: .ELSEIF uMsg==WM_PAINT:

Quote.ELSEIF uMsg==WM_PAINT
        invoke BeginPaint,hWnd, ADDR ps
        mov    hdc,eax
        ;================================ FONT ======================================
        invoke CreateFont,16,0,0,0,400,0,0,0,OEM_CHARSET,\
                               OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
                               DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,\
                               ADDR FontName
        invoke SelectObject, hdc, eax
        mov    hfont,eax
        RGB    255,255,255
        invoke SetTextColor,hdc,eax
        RGB    50,50,50
        invoke SetBkColor, hdc,eax
       
        ;================================ RENDERER ===================================

        xor edi, edi                              ;Loop
        mov esi, 1                                ;esi= y coord of line 1
           @@:
            mov hitpoint.x, 300
            m2m hitpoint.y, esi
                                                  ;--- MOD ArrayLineOffset & Multiply ---
            mov eax, ArrayLineOffset                  ;MOD ArrayLineOffset
            mov ebx, cHEIGHT
            cdq                             
            div ebx
            mov ArrayLineOffset, edx                  ;MOD value
   
            mov eax, ArrayLineOffset
            mov ebx, cWIDTH
            mul ebx                                   ;get array. eax= array offset (index)
                           
            invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR Map+[eax], cWIDTH
   
            add esi, 15                               ;(tYPos)
            inc ArrayLineOffset
            inc edi                                   ;loop increment
            cmp edi, cHEIGHT   
            jb @B
        invoke SelectObject,hdc, hfont                ;closes font
        invoke EndPaint,hWnd, ADDR ps                 ;End Paint
    .ELSEIF     uMsg==WM_DESTROY
        invoke PostQuitMessage,NULL       
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .ENDIF


:icon_confused: The prog has a problem though :icon_confused::

It starts running with 3.150 bytes, but the memory usage keeps getting higher and higher. Around 10.000 something happens... (same result if I loose the font code)

ps: Guys, I just completed my first week in MASM!
Title: Re: "Hello masm32", not a BOT, new member
Post by: fearless on February 04, 2017, 09:23:18 AM
CreateFont would ideally be placed in some other part of the program, at startup, initialization routine etc, where the font handle is saved.


        invoke CreateFont,16,0,0,0,400,0,0,0,OEM_CHARSET,\
                               OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
                               DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,\
                               ADDR FontName
        mov    hfont,eax


Can be moved to WM_INITDIALOG or something else.

The old font object is probably still being leaked when selecting and clearing it i suspect. I would have an hOldFont handle when using the SelectObject and restore once finished with it.

Something like:

Invoke SelectObject, hdc, hFont
mov hOldFont, eax

.
.
. do some stuff with text and font
.
.
.
Invoke SelectObject, hdc, hOldFont



Of course there could be a resource leak elsewhere or something else ive forgotten.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 04, 2017, 09:41:41 AM
You are totally right!  I'll move the font code  to another place. I thought of that but didn't implemented. Even I will need more than one font.

I commented the font code and the leak persists
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 04, 2017, 06:41:29 PM
Just checked, it´s the font that´s leaking memory.

I moved the code into WM_INITDIALOG, and also to WM_CREATE, but nothing happens in both places
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 05, 2017, 01:14:42 PM
Follow the zip code with prog4 fixed. No more memory leak, it´s steady at 3.132 bytes.
It was the font thing

Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 05, 2017, 02:25:02 PM
Good you have chased it down.  :t
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 05, 2017, 02:42:33 PM
Quote from: hutch-- on February 05, 2017, 02:25:02 PM
Good you have chased it down.  :t

Thanks!

By the way, I´m doing these progs in increment to learn and improve piece by piece.
The idea is to make a re-creation of the Atari game "River Raid", in ascii. This scrolling experiment is the idea for the game´s map rolling down.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 08, 2017, 05:19:52 PM
An update! And a world of questions....

So, still testing the waters... I made a temporary map of something closer to a River Raid level map.
The thing runs and stops when we reach the end of it.

There´s no game logic at all. I´m still trying things out.

I´m really on my own here, any help would be really appreciated!

I´m using the Window´s loop as my game loop.
I need a timer to control my game flow/speed. This was the best I could come out with. Any better solution?
Quoteinvoke GetTickCount  ;Timer
      mov tMyTick, eax
            .WHILE TRUE

                invoke GetMessage, ADDR msg,NULL,0,0
                .BREAK .IF (!eax)
                invoke DispatchMessage, ADDR msg
               
                ;=========================================================
                ;=============== MY GAME LOOP HERE!!!! ===================
                ;=========================================================
                ; My calling points here
                ; call pGame proc
                ; call pColisionDetection

                tTimer:                                                 ;Controlling speed                                     
                      invoke GetTickCount
                      sub eax, tMyTick
                      cmp eax, 40               ;waits x ticks
                      jb tTimer
                      invoke GetTickCount
                      mov tMyTick, eax

                invoke InvalidateRect,hwnd, ADDR mapRect, FALSE          ;All done, render:
            .ENDW

As an ascii game, I´m stuck with the WM_PAINT Msg, so I´m leaving all my rendering there.
(Man is that green A on screen. It´s gonna be the player´s boat.. or whatever)
Quote.ELSEIF uMsg==WM_PAINT
            ;invoke  GetTickCount                ;******** timing
            ;mov DebugTick, eax                  ;******** timing

        invoke BeginPaint,hWnd, ADDR ps
        mov    hdc,eax

        ;===== BK MAP ===============
        ;============================
        invoke SelectObject, hdc, Font1           ;select font
        RGB    255,255,255
        invoke SetTextColor,hdc, eax
        RGB    50,50,50
        invoke SetBkColor, hdc, eax
        invoke SetBkMode, hdc, OPAQUE
                                                  ;render map
                                                  ;(cHEIGHT-ArrayLineOffset)*cWIDTH...
                                                  ;...ArrayLineOffset increases until = cHEIGHT
        mov eax, cHEIGHT            ;(avoiding interdependancy)
        mov ebx, cWIDTH
        mov esi, offset Map         
        sub eax, ArrayLineOffset
        mov edi, 80                 ;loop counter
        mul ebx                     ;eax= lineOffset addr
        mov hitpoint.x, 80          ;loc x   
        add esi, eax                ;initial address to textout

        mov hitpoint.y, 1           ;loc of line 1

    @@:
        invoke TextOut,hdc,hitpoint.x,hitpoint.y, ADDR [esi], ebx
        add esi, ebx                ;next line

        add hitpoint.y, 10          ;y pos inc
        dec edi                     ;loop counter
        jnz @B
            ;invoke GetTickCount                         ;******** timing **********
            ;sub eax, DebugTick                          ;******** timing **********
            ;print str$(eax),13,10                       ;******** timing **********

        ;============================
        ;===== MAN ==================
        ;============================

        invoke SelectObject, hdc, Font2           ;select font
        RGB    0,255,0
        invoke SetTextColor,hdc, eax
        RGB    50,50,50
        invoke SetBkColor, hdc, eax
        invoke SetBkMode, hdc, TRANSPARENT
        invoke TextOut,hdc,0,600, ADDR Man, cWIDTH
        ;=====================================================================
        ;===== End of Map? ===================================================
        mov eax, cHEIGHT                        ;if it´s 0 then we reached
        cmp eax, ArrayLineOffset                ;       the top of the map
        jz LevelEnd

        inc ArrayLineOffset
        jmp PaintEnds
       
LevelEnd:                                             ;==Reached the end of Map. Level is over
        invoke EndPaint,hWnd, ADDR ps                 ;End Paint
        ret
PaintEnds:
        invoke EndPaint,hWnd, ADDR ps                 ;End Paint

.I need this map to be really optimized. Am I too bad? How can I make it faster
.I tried to time my code with the commented GetTickCount and related. I´m sure it´s not actually working as it should. Help...please

Lastly, this experiment has a major flaw: Every time one moves the mouse, Windows stops scrolling to do its things. I need to find a way to make it non stop. Honestly, I don´t know how

Cheers, Alex
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 08, 2017, 06:09:39 PM
I would be inclined to use a timer as the loop you are using to get the delay is causing the problem with the mouse. I am rusty in this area but a multi-media timer used to have far better resolution. What processor are you using ? This may effect the thread timings depending on the core count.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 08, 2017, 06:21:34 PM
Quote from: hutch-- on February 08, 2017, 06:09:39 PM
I would be inclined to use a timer as the loop you are using to get the delay is causing the problem with the mouse. I am rusty in this area but a multi-media timer used to have far better resolution. What processor are you using ? This may effect the thread timings depending on the core count.

Hi Hutch,
Win7 Professional 64bits
Intel Core i7-4790
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 08, 2017, 06:25:23 PM
Hutch, the mouse is not delaying, it´s actually halting the WM_PAINT.
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 08, 2017, 07:28:57 PM
OK, hardware is fast enough with enough threads, when you set up a timer it is placed in another thread by the OS so you app should not have any lag in it.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 08, 2017, 07:48:30 PM
Quote from: hutch-- on February 08, 2017, 07:28:57 PM
OK, hardware is fast enough with enough threads, when you set up a timer it is placed in another thread by the OS so you app should not have any lag in it.

Ok, I see what I can do!
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 09, 2017, 04:16:30 PM
GOT IT!
At least for now that will do. I realised I was doing something stupid create an unnecessary loop hook in my timer. I´m using an .If.

Quoteinclude \masm32\include\winmm.inc
    includelib \masm32\lib\winmm.lib
...
It´s a timeGetTime in winmm.lib
Quoteinvoke timeGetTime 
                sub eax, MyTime
                .IF eax>=80
                    invoke InvalidateRect,hwnd, ADDR mapRect, FALSE          ;All done, render:
                    invoke timeGetTime                                       ;retrieve next Starting time
                    mov MyTime, eax
                .ENDIF


ps: Included the missing Level1.txt in the zip file
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 10, 2017, 04:57:37 AM
 :t

This works fine on my Win10 64 bit.  :biggrin:

Interstingly I have not seen ascii animation for years. Once long ago I watched an ascii art version of star wars and you could follow what was happening.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 10, 2017, 01:32:40 PM
Quote from: hutch-- on February 10, 2017, 04:57:37 AM
Interstingly I have not seen ascii animation for years. Once long ago I watched an ascii art version of star wars and you could follow what was happening.

Thanks Hutch. Yes, ascii animation is fun but has been out of the loop for a while. I thought it would be a nice project as a beginner not to have to deal with more complex graphics, an ascii little game could be acomplishable. In fact, it could even turn into a nice tutorial for newbies like me...

I will keep doing this project as I am, step by step, without jumping ahead of myself. Every little step teaches me something new, and that´s the goal.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 11, 2017, 02:39:59 AM
A benchmark test between:

Quote.WHILE TRUE
   invoke PeekMessage, ADDR msg, NULL, 0, 0, PM_REMOVE
      .IF (eax != 0) ......
(using timeGetTime)

and
Quote.WHILE TRUE
      invoke GetMessage, ADDR msg, NULL, 0, 0; , PM_REMOVE
      .IF (eax != 0)......
using WM_TIMER

The 2 versions in the zip file.

timeGetTime vs TIMER (millisecs):

at 10:
timeGetTime   31-32            CPU: 11.88
TIMER      31-32            CPU: 11.66

at 40
timeGetTime   15-16   rare peaks: 31      CPU: 11.60
TIMER      15-16   rare peaks: 31      CPU: 6.85

at 80:
timeGetTime   15-16   rare peaks: 31      CPU: 11.88
TIMER      31-47   rare peaks: 16      CPU: 5.08

at 120:
timeGetTime   15-16   rare peaks: 31      CPU: 11.88
TIMER      31-47            CPU: 4.40




Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 14, 2017, 02:14:14 PM
So, my map file was about 89.999 bytes and it´s too big, since I will need many.

I decided to optmize it.
With the code bellow I manage to turn the Level1.txt (89.999) into an array of 8.488 bytes.

It´s an array of pairs. Each pair reads "charValue", "lenght". So @@@@@@@@@@ gives 64,10.
The code works, but I have a stupid question I admit I couldn´t find the answer:

I wanted to put charValue into "bh", and the sum of chars into "bl". I thought if I pass "bx" to the array I had the right order. But it´s not... I manually inverted bh, bl, for bl, bh to have it right... What am I missing?

BX ->  BH, BL in this order, right?
I´m getting the other way around: BX-> BL, BH


QuoteThis should be in bh:
mov   bl, [esi + edi]                              ; the value for the new char in bl----------- Fills bl


This should be in bl:
add bh, 1                              ; it´s the same char, add sum in bh ------------------- sum in bh


Here I pass them to the array:
mov [eax], bx                        ; send the 2 bytes to dest array

Here is the complete procedure:
start:
      invoke pLoad, offset Filename
      inkey
      invoke ExitProcess, eax

pLoad proc, string:DWORD
            LOCAL       tLen :DWORD
            LOCAL    MapIndex:DWORD

          mov   esi, InputFile(string)                    ; esi is source   
          mov   tLen, ecx                                    ; lenght of file in tLen (returns in ecx)
    new:
          xor   ebx, ebx                                          ; bl= char  bh= char count
          mov   bl, [esi + edi]                              ; the value for the new char in bl----------- Fills bl
          mov   bh, 1                                              ; sum acumulator to 1
    same:   
          add    edi, 1                              ; add counter
          cmp   edi, tLen                 ; end of file?
          jz       done                              ; we are done
         
          cmp   bl, [esi + edi]                  ; comp char in bl with current
          jnz   notEqual

          ;it´s an equal char
          add bh, 1                              ; it´s the same char, add sum in bh ------------------- sum in bh
          jmp same                              ; jumps 'same'

    notEqual:                                    ; it´s a new sequence of the same new char
          mov eax, offset Map
          add eax, MapIndex
          mov [eax], bx                        ; send the 2 bytes to dest array
          add MapIndex, 2                  ; update dest array index
          jmp new                               ; 'new' sets the new char to bl

    done:
          free esi
          xor      edi, edi                                          ; edi is index

          printf ("Original size= %d ", tLen)
          print " ",13,10
          printf ("New size=  %d   ", MapIndex)
          print " ",13,10

      ret
pLoad endp   
end start


JJ, this f11 function in RichMasm is Fantastic!!
Title: Re: "Hello masm32", not a BOT, new member
Post by: mineiro on February 15, 2017, 01:01:24 AM
hello LordAdef;
"little endian" and big endian is about your question.

mov [eax], bx                        ; send the 2 bytes (grouped) to dest array

on line above, if bx == 0102h , when you store this value from register to memory their order changes because you're dealing with word, so will be stored on memory as 0201h.
Just check this, after store a word,dword, qword on memory, get only one byte from that address instead of more than 1 byte and you will see the point.
mov [eax],12345678h   ;a double word, 4 bytes group stored on address pointed by eax register
So, on memory that will look like
[rax] pointed address contents == 78563412h

offtopic: Oh yes LordAdef, I'm from Minas Gerais, yes, this slogan is about Rauzlito. Good to see brothers here trying the Latim language of computers.
Title: Re: "Hello masm32", not a BOT, new member
Post by: FORTRANS on February 15, 2017, 01:07:57 AM
Hi,

   X86 is little endian, which means when you store a register to
memory, its apparent byte order becomes reversed.  For the BX
register, you can use the old DOS DEBUG to see what/how that
happens.  Or there are endless tutorials and discussions on endian-
ness fun out and about the web.

HTH,

Steve N.

P.S.  While typing I was scooped (someone beat me to answer.).

SRN
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 15, 2017, 02:01:22 AM
A couple of things here, Steve is right about the byte order of a 32 bit register if you think of 4 bytes labeled 0123, in memory they are stored as 3210 and this is a characteristic of x86 hardware. It catches people who are learning because byte data like text is stored left to right but numbers are stored in reverse order. In 32 bit you can access the two lowest bytes with AL and AH but for a long time Intel have advised against using the high byte and it 64 bit you cannot access it at all.

If you can manage it, do all of your BYTE register reads and writes in the low byte register AL/BL/CL etc .... It takes a bit more organisation so you don't run out of registers but a lesson I have learnt writing 64 bit algos, the ones I wrote properly in win32 easily converted to Win64 where the odd one or two were pigs that had to be rewritten because you could not access the high byte directly. You can still indirectly access any of the last 3 bytes of a DWORD by using rotates or shifts but it is slower as shifts and rotates are not fast instructions.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 15, 2017, 03:47:33 AM
Bollocks!!!

And I knew about Endian order!! That proves the fact the one can only learn Assembly by practicing....  I was so focused on the algorithm that missed that...

Thanks Mineiro, Steve and Hutch!

Mineiro, my wife asked me why I am learning Assembly. I said I want to become a Painter, not a Photoshop editor (no offense intended). Well, that's how I feel about asm.

Hutch, any specific reason why intel suggested not using the high byte?
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 15, 2017, 04:01:58 AM
Quote from: hutch-- on February 15, 2017, 02:01:22 AMIn 32 bit you can access the two lowest bytes with AL and AH but for a long time Intel have advised against using the high byte and it 64 bit you cannot access it at all.

Well, ah is not completely inaccessible (but you probably meant something else):

include \Masm32\MasmBasic\Res\JBasic.inc      ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)

Init            ; OPT_64 1      ; put 0 for 32 bit, 1 for 64 bit assembly
  PrintLine Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format")
  mov ah, 123
  ; movzx rax, ah      ; not possible
  movzx eax, ah      ; workaround; same result as movzx rax, ah but shorter
  Print Str$("If ah is 123, then rax is now %lli\n\n", rax)
  mov rax, 1234567890123456789
  Inkey Str$("rax can be a really big number: %lli\n", rax)
EndOfCode


Output:
This code was assembled with HJWasm32 in 64-bit format
If ah is 123, then rax is now 123

rax can be a really big number: 1234567890123456789
Title: Re: "Hello masm32", not a BOT, new member
Post by: mineiro on February 15, 2017, 05:50:39 AM
Quote from: LordAdef on February 15, 2017, 03:47:33 AM
Mineiro, my wife asked me why I am learning Assembly. I said I want to become a Painter, not a Photoshop editor (no offense intended). Well, that's how I feel about asm.
:eusa_clap:
I share the same opinion, persons that learn assembly are persons that don't simply accept things but like to understand the magic behind curtains.
You said about Photoshop, well, we can use photoshop as being a hexadecimal editor, but instead of see hexadecimal numbers we see colors, so, on theory we can program in assembly language by using Photoshop, it's hard I confess, but not impossible. Inverse can be done too, we can use an assembler to create a .gif,.bmp,..., it's hard but not impossible.
You're being a musician the same thing, but instead of see hexadecimal numbers on Audacity per example we see sinoidal waves.
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 15, 2017, 10:58:58 AM
> Hutch, any specific reason why intel suggested not using the high byte?

The reasoning from Intel at the time was it was a slower operation because of how the register was loaded and I think it goes back to the PIV era. You have had 2 major series of Intel hardware since, the Core2 series and the i3/5/7 series which may vary or are no longer bothered by it but for 64 bit operations, the high byte register is not available. JJ has shown how to access AH with a 32 bit operation but for a 64 bit operation, there is no opcode that will do it.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 15, 2017, 12:37:35 PM
Quote from: hutch-- on February 15, 2017, 10:58:58 AMit was a slower operation because of how the register was loaded and I think it goes back to the PIV era.

Here is a little testbed:
align_64
TestA_s:
NameA equ mov al ; assign a descriptive name here
TestA proc
  mov ebx, AlgoLoops-1 ; loop e.g. 100x
  align 4
  .Repeat
mov al, byte ptr somestring
mov cl, al
inc al
movzx eax, al
dec ebx
  .Until Sign?
  ret
TestA endp
TestA_endp:

align_64
TestB_s:
NameB equ mov ah ; assign a descriptive name here
TestB proc
  mov ebx, AlgoLoops-1 ; loop e.g. 100x
  align 4
  .Repeat
mov ah, byte ptr somestring
mov ch, ah
inc ah
movzx eax, ah
dec ebx
  .Until Sign?
  ret
TestB endp
TestB_endp:


Results:Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz (SSE4)

127     cycles for 100 * mov al
53      cycles for 100 * mov ah

130     cycles for 100 * mov al
55      cycles for 100 * mov ah

126     cycles for 100 * mov al
52      cycles for 100 * mov ah

129     cycles for 100 * mov al
55      cycles for 100 * mov ah

127     cycles for 100 * mov al
55      cycles for 100 * mov ah

12      bytes for mov al
13      bytes for mov ah


The ah stuff is definitely one byte longer.
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 15, 2017, 03:05:56 PM
I tried to access the source code but it is unreadable RTF. What I would test is turning the two loops around because at the moment the code you posted is indicating that AH is faster than AL which does not make sense.

Posting examples in an unreadable format makes testing your algorithms unviable which is unfortunate because it renders them useless.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 15, 2017, 06:03:14 PM
Quote from: hutch-- on February 15, 2017, 03:05:56 PM
I tried to access the source code but it is unreadable RTF.

RTF has been readable for almost 30 years now. Wordpad, for example, can read it; also MS Word, RichMasm (http://masm32.com/board/index.php?topic=5314.0), LibreOffice, ...

QuoteWhat I would test is turning the two loops around because at the moment the code you posted is indicating that AH is faster than AL which does not make sense.

Given that there is a REPEAT 5 ... ENDM around the code examples, there is obviously no need to exchange the order of the loops.

Anyway, for those who are not able to read RTF, attached a plain text version with loops "turned around". I agree, of course, that it "does not make sense" that ah is faster than al - maybe you can code something where it is the other round. Btw there is a switch in line 3 of the source: useMB=0 - the second attachment contains the exe without any trace of MasmBasic (4096 bytes only), maybe the AH register behaves better without the influence of that library.
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz (SSE4)

57      cycles for 100 * mov ah
129     cycles for 100 * mov al

56      cycles for 100 * mov ah
122     cycles for 100 * mov al

56      cycles for 100 * mov ah
129     cycles for 100 * mov al

56      cycles for 100 * mov ah
129     cycles for 100 * mov al

56      cycles for 100 * mov ah
129     cycles for 100 * mov al

13      bytes for mov ah
12      bytes for mov al
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 16, 2017, 02:59:02 AM
 :biggrin:

> RTF has been readable for almost 30 years now. Wordpad, for example, can read it; also MS Word, RichMasm, LibreOffice, ...

Trouble is that assemblers and compiler can't read it. Locking in a deviant code format to an exclusive editor makes the files unbuildable with anything else. Unless M$ have updated Word and Wordpad recently, they will not assemble MASM source code. Without a viable method to test the algos you post, there is no way of knowing what they do or how they are written.

With MASM it can be built with a batch file that does not require an editor at all and that can be tested by anyone who has a normal ascii text editor, Notepad and a whole host of others.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 16, 2017, 03:36:50 AM
Quote from: hutch-- on February 16, 2017, 02:59:02 AMthere is no way of knowing what they do or how they are written.

You could open rich text (*.asc) files in Wordpad to see how they are written. If you don't trust my executables, you can press Ctrl A, Ctrl C, then switch to a poor text editor of your choice and build it there.

Never mind, from now on I'll try to add the poor text versions, too.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 16, 2017, 05:28:53 AM
curious to know what's happening with al and ah in this code. it's an odd result indeed
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 16, 2017, 05:58:03 AM
Here is a simple benchmark testing the load time of AL and AH. Done on my 3.3 gig 6 core HASWELL.

This is the result.

688 load AL
1015 load AH
703 load AL
985 load AH
718 load AL
1000 load AH
735 load AL
984 load AH
703 load AL
1032 load AH
671 load AL
969 load AH
735 load AL
984 load AH
687 load AL
1000 load AH
Press any key to continue ...


This is the code.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    .data?
      value dd ?

    .data
      item dd 0

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    push ebx
    push esi
    push edi

    mov edi, 8

  lpstart:

  ; -----------------------------------------------------------

    mov esi, 1024*1024*1024     ; a power of 2, billion.
    mov dl, 0

    invoke GetTickCount
    push eax

  @@:
    mov al, dl                  ; load AL
    add dl, 1
    cmp dl, 255
    jne nxt
    mov dl, 0
  nxt:
    sub esi, 1
    jnz @B

    invoke GetTickCount
    pop ecx
    sub eax, ecx

    print str$(eax)," load AL",13,10

  ; -----------------------------------------------------------

    mov esi, 1024*1024*1024     ; a power of 2 billion.
    mov dl, 0

    invoke GetTickCount
    push eax

  @@:
    mov ah, dl                  ; load AH
    add dl, 1
    cmp dl, 255
    jne nxt1
    mov dl, 0
  nxt1:
    sub esi, 1
    jnz @B

    invoke GetTickCount
    pop ecx
    sub eax, ecx

    print str$(eax)," load AH",13,10

  ; -----------------------------------------------------------

    sub edi, 1
    jnz lpstart

    pop edi
    pop esi
    pop ebx

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 16, 2017, 09:33:02 AM
Interesting :t

I found my example a bit more relevant for practical purposes, but no problem, you found a case where mov ah is slow, congrats :icon14:

Btw how do the timings change with an align 4 before the two loops?
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 16, 2017, 11:24:39 AM
 :biggrin:

> I found my example a bit more relevant for practical purpose

I took Intel's word on it and it seems like they know what they are talking about as they designed the hardware. May be different on AMD.

> Btw how do the timings change with an align 4 before the two loops?

I rarely ever align code these days as it often slows the code down. It was helpful at time with very old hardware, pre PIV but from the PIV onwards it often has the reverse effect.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 16, 2017, 12:33:00 PM
Quote from: hutch-- on February 16, 2017, 11:24:39 AM

> Btw how do the timings change with an align 4 before the two loops?

I rarely ever align code these days as it often slows the code down. It was helpful at time with very old hardware, pre PIV but from the PIV onwards it often has the reverse effect.

With new hardware, such as my Core i5, an align 4 definitely speeds up the mov ah part.
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 16, 2017, 02:57:25 PM
> With new hardware, such as my Core i5, an align 4 definitely speeds up the mov ah part

This is possibly the case as the Intel data indicated that a read or write to a high byte register involves an extra operation that is slower than a read/write to a low byte register and very vaguely it had to do with a masking operation to get the high byte.

I will make the point though that writing legacy code in either 32 or 64 bit is a mistake, it simply cannot be done as a 64 bit operation and while your example in 32 bit in 64 bit code did work, you will get stung in performance terms by doing things like that. At least in 64 bit code you have more BYTE registers which removes the need to use antique code.
Title: Re: "Hello masm32", not a BOT, new member
Post by: nidud on February 16, 2017, 10:50:13 PM
deleted
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 16, 2017, 11:42:19 PM
Quote from: nidud on February 16, 2017, 10:50:13 PM
Here's a simple 64-bit test-bed without any alignment problems.

Can't be :(

Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz (AVX)
----------------------------------------------
-- test(1)
   553579 cycles, rep(3000), code(801) 0.asm: load AL
   428491 cycles, rep(3000), code(801) 1.asm: load AH
-- test(2)
   539858 cycles, rep(3000), code(801) 0.asm: load AL
   429470 cycles, rep(3000), code(801) 1.asm: load AH
-- test(3)
   532109 cycles, rep(3000), code(801) 0.asm: load AL
   433764 cycles, rep(3000), code(801) 1.asm: load AH

total [1 .. 3], 1++
  1291725 cycles 1.asm: load AH
  1625546 cycles 0.asm: load AL
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 17, 2017, 01:10:00 AM
Here is what it looks like in 64 bit MASM, the load to AH is even slower.

Run on my 3.3gig Haswell.

703 load AL
1203 load AH
656 load AL
1172 load AH
672 load AL
1156 load AH
672 load AL
1203 load AH
719 load AL
1156 load AH
672 load AL
1156 load AH
672 load AL
1156 load AH
672 load AL
1156 load AH

That's all folks .....


RE: The testing method. The virtues of real time testing versus interpreted testing.

File attached.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 17, 2017, 01:18:33 AM
    mov rsi, 1024*1024*1024     ; a power of 2, billion.
    mov dl, 0

    invoke GetTickCount
    push rax

  @@:                           ; -------
    mov ah, dl                  ; load AH  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    add dl, 1                   ; -------
    cmp dl, 255
    jne nxt1
    mov dl, 0
  nxt1:
    sub rsi, 1


So at least we now have an official confirmation that AH can be used in 64-bit code. But the mystery remains:
1. why is Nidud's test so much faster for AH? repeat 200
mov dl,ah
mov ah,bl
endm


2. why is Hutch' test so much slower for AH?  @@:                           ; -------
    mov ah, dl                  ; load AH
    add dl, 1                   ; -------
    cmp dl, 255
    jne nxt1
    mov dl, 0
  nxt1:
    sub rsi, 1
    jnz @B


Anybody here from Intel who could enlighten us?

P.S.: What does the 64-bit Windows ABI say about preserving regs?
    mov dl, 0
    invoke GetTickCount
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 17, 2017, 01:31:54 AM

> 2. why is Hutch' test so much slower for AH?

Testing in real time !

Here is a variation on the first test, remove the PUSH POP from both examples and the load AH code got faster. Replace it with r15. The load AH is still a lot slower

703 load AL
1031 load AH
703 load AL
985 load AH
687 load AL
1063 load AH
734 load AL
1016 load AH
687 load AL
1016 load AH
687 load AL
1016 load AH
703 load AL
1016 load AH
734 load AL
1016 load AH

That's all folks .....


The code.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    LOCAL .rsi  :QWORD
    LOCAL .rdi  :QWORD
    LOCAL .r15  :QWORD

    mov .rsi, rsi
    mov .rdi, rdi
    mov .r15, r15

    mov rdi, 8                  ; the loop counter

  lpstart:

  ; -----------------------------------------------------------

    mov rsi, 1024*1024*1024     ; a power of 2, billion.
    mov dl, 0

    invoke GetTickCount
    mov r15, rax

  @@:                           ; -------
    mov al, dl                  ; load AL
    add dl, 1                   ; -------
    cmp dl, 255
    jne nxt
    mov dl, 0
  nxt:
    sub rsi, 1
    jnz @B

    invoke GetTickCount
    mov rcx, r15
    sub rax, rcx

    conout str$(rax)," load AL",lf

  ; -----------------------------------------------------------

    mov rsi, 1024*1024*1024     ; a power of 2, billion.
    mov dl, 0

    invoke GetTickCount
    mov r15, rax

  @@:                           ; -------
    mov ah, dl                  ; load AH
    add dl, 1                   ; -------
    cmp dl, 255
    jne nxt1
    mov dl, 0
  nxt1:
    sub rsi, 1
    jnz @B

    invoke GetTickCount
    mov rcx, r15
    sub rax, rcx

    conout str$(rax)," load AH",lf

  ; -----------------------------------------------------------

    sub rdi, 1
    jnz lpstart

    conout lf
    waitkey "That's all folks ....."

    mov rsi, .rsi
    mov rdi, .rdi
    mov r15, .r15

    invoke ExitProcess,0

    ret

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
Title: Re: "Hello masm32", not a BOT, new member
Post by: nidud on February 17, 2017, 01:45:27 AM
deleted
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 17, 2017, 01:56:30 AM
Thanks for that, I don't have an AMD box to test with.
Title: Re: "Hello masm32", not a BOT, new member
Post by: TWell on February 17, 2017, 03:05:37 AM
Another AMD E1
3328 load AL
3297 load AH
3281 load AL
3266 load AH
3297 load AL
3297 load AH
3265 load AL
3282 load AH
3281 load AL
3281 load AH
3281 load AL
3297 load AH
3282 load AL
3265 load AH
3297 load AL
3281 load AH

That's all folks .....
Title: Re: "Hello masm32", not a BOT, new member
Post by: FORTRANS on February 17, 2017, 03:22:47 AM
Hi,

   FWIW.

; - - -
{P-III}
; - - -
pre-P4 (SSE1)

104   cycles for 100 * mov ah
105   cycles for 100 * mov al

104   cycles for 100 * mov ah
105   cycles for 100 * mov al

103   cycles for 100 * mov ah
105   cycles for 100 * mov al

105   cycles for 100 * mov ah
108   cycles for 100 * mov al

104   cycles for 100 * mov ah
104   cycles for 100 * mov al

13   bytes for mov ah
12   bytes for mov al


--- ok ---

; - - -
P-MMX
; - - -
pre-P4
489   cycles for 100 * mov ah
505   cycles for 100 * mov al

489   cycles for 100 * mov ah
513   cycles for 100 * mov al

529   cycles for 100 * mov ah
592   cycles for 100 * mov al

496   cycles for 100 * mov ah
517   cycles for 100 * mov al

499   cycles for 100 * mov ah
518   cycles for 100 * mov al

13   bytes for mov ah
12   bytes for mov al


--- ok ---

; = = =

Intel(R) Core(TM) i3-4005U CPU @ 1.70GHz (SSE4)

74   cycles for 100 * mov ah
163   cycles for 100 * mov al

74   cycles for 100 * mov ah
162   cycles for 100 * mov al

74   cycles for 100 * mov ah
162   cycles for 100 * mov al

74   cycles for 100 * mov ah
162   cycles for 100 * mov al

74   cycles for 100 * mov ah
162   cycles for 100 * mov al

13   bytes for mov ah
12   bytes for mov al


--- ok ---

; - - -

Intel(R) Core(TM) i3-4005U CPU @ 1.70GHz (AVX2)
----------------------------------------------
-- test(1)
   613736 cycles, rep(3000), code(801) 0.asm: load AL
   542611 cycles, rep(3000), code(801) 1.asm: load AH
-- test(2)
   620431 cycles, rep(3000), code(801) 0.asm: load AL
   535470 cycles, rep(3000), code(801) 1.asm: load AH
-- test(3)
   628891 cycles, rep(3000), code(801) 0.asm: load AL
   532790 cycles, rep(3000), code(801) 1.asm: load AH

total [1 .. 3], 1++
  1610871 cycles 1.asm: load AH
  1863058 cycles 0.asm: load AL
hit any key to continue...


HTH,

Steve N.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 17, 2017, 04:10:49 AM
  align 8
@@:
mov ah, byte ptr somestring
mov ch, ah
inc ah
movzx eax, ah
dec ebx
jns @B


  align 8
@@:
mov al, byte ptr somestring
mov cl, al
inc al
movzx eax, al
dec ebx
jns @B


Results for a Core i5, one Billion iterations:This code was assembled with ML in 64-bit format
671 ms for AH
1014 ms for AL

655 ms for AH
983 ms for AL

656 ms for AH
982 ms for AL

640 ms for AH
983 ms for AL

671 ms for AH
982 ms for AL


No speed difference between 64-bit and 32-bit code. Sources (rich text, poor text) and executables built with ML, ML64, AsmC and HJWasm32 attached.

P.S.: What exactly is "real time", and how is it different to what?
Quote from: hutch-- on February 17, 2017, 01:31:54 AMTesting in real time !
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 17, 2017, 06:59:30 AM
I wouldn't have imagined such different results...

I'll run the test here and post my results too. Win7 64b on i7
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 17, 2017, 11:52:37 AM
 :biggrin:

> P.S.: What exactly is "real time", and how is it different to what?

The stuff you wake up to in the morning, stop to each your lunch by, go to the pub after work by and what you set the alarm clock for. I have warned you for a long time that your timing technique is unsound, there are too many interpretive layers and too many variables that can produce misleading results. The other factor is that cycle counts went out the door with a 486dx.

The reason why I still use a very crude low level timing technique run long enough to avoid task switching is because it assumes only 1 thing, how long it takes. Using misleading timing techniques may justify using obsolete instructions but you won't get fast code for doing it.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 17, 2017, 06:56:54 PM
Quote from: hutch-- on February 17, 2017, 11:52:37 AMI have warned you for a long time that your timing technique is unsound

Thanks for the warning. I am so sorry that you consider my coding garbage (http://masm32.com/board/index.php?topic=5962.msg63519#msg63519), Hutch, but please explain to me how I could improve the loops below to make them "sound real timing"?

From attachment to Reply #87, MovAh_JJ_DualAssembly.asm (plain text, opens even in qEditor.exe):
MainLoop:
  mov ebx, AlgoLoops-1 ; OxPT_Assembler ML ; delete the x to pick another assembler
  push rax ; keep the stack aligned
  push rv(GetTickCount)
  align 8
@@:
mov ah, byte ptr somestring
mov ch, ah
inc ah
movzx eax, ah
dec ebx
jns @B
  jinvoke GetTickCount
  pop rdx
  pop rcx
  sub rax, rdx
  Print Str$("%i ms for AH\n", rax)

  mov ebx, AlgoLoops-1
  push rax ; keep the stack aligned
  push rv(GetTickCount)
  align 8
@@:
mov al, byte ptr somestring
mov cl, al
inc al
movzx eax, al
dec ebx
jns @B
  jinvoke GetTickCount
  pop rdx
  pop rcx
  sub rax, rdx
  Print Str$("%i ms for AL\n\n", rax)
  dec esi
  jns MainLoop
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 17, 2017, 07:42:16 PM
There is not enough in your snippet to make sense of it. Missing bits and limited commenting.
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 17, 2017, 08:45:28 PM
Here is an even less interpreted benchmark, 2 x 3 instruction loops ran 8 times sequentially and displayed on the screen. I have done everything I could think of to try and stabilise the timings of the high byte to high byte register copies, aligned each label by 16, set a higher priority class, untangled the mixed 32/64 bit instructions but the low byte register copies are clearly faster on this Haswell I am using. Still, I don't understand why you want to use legacy code like this when you have a lot more registers to work with.

984 ms high byte load
672 ms low byte load
1031 ms high byte load
687 ms low byte load
1016 ms high byte load
672 ms low byte load
1016 ms high byte load
657 ms low byte load
1000 ms high byte load
625 ms low byte load
984 ms high byte load
656 ms low byte load
1000 ms high byte load
640 ms low byte load
1000 ms high byte load
672 ms low byte load
Press any key to continue...

This is the test piece.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    LOCAL .rsi  :QWORD
    LOCAL .rdi  :QWORD
    LOCAL .rbx  :QWORD
    LOCAL .r15  :QWORD

    mov .r15, r15
    mov .rbx, rbx
    mov .rdi, rdi

    invoke SetPriorityClass,rv(GetCurrentProcess),HIGH_PRIORITY_CLASS

    chnm equ <255>              ; single number to write
    lcnt equ <1024*1024*1024*2> ; loop iteration count
    algn equ <16>               ; alignment
    dlay equ <100>              ; delay for SleepEx

    mov rdi, 8

  startlabel:

; ----------------------------

    invoke SleepEx,dlay,0

    mov rbx, lcnt
    invoke GetTickCount
    mov r15, rax

    xor rax, rax
    xor rdx, rdx

    mov dh, chnm

  align algn
  @@:
    mov ah, dh                  ; load HIGH BYTE to HIGH BYTE
    sub rbx, 1
    jns @B

    invoke GetTickCount
    sub rax, r15
    conout str$(rax)," ms high byte load",lf

; ----------------------------

    invoke SleepEx,dlay,0

    mov rbx, lcnt
    invoke GetTickCount
    mov r15, rax

    xor rax, rax
    xor rdx, rdx

    mov dl, chnm

  align algn
  @@:
    mov al, dl                  ; load LOW BYTE to LOW BYTE
    sub rbx, 1
    jns @B

    invoke GetTickCount
    sub rax, r15
    conout str$(rax)," ms low byte load",lf

; ----------------------------

    sub rdi, 1
    jnz startlabel

    invoke SetPriorityClass,rv(GetCurrentProcess),NORMAL_PRIORITY_CLASS

    waitkey

    mov r15, .r15
    mov rbx, .rbx
    mov rdi, .rdi

    invoke ExitProcess,0

    ret

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 20, 2017, 04:56:05 PM
Hi there, I´m still doing my things and I believe I´m making some progress....

I´m attaching below 2 little progs for you.

The first one is a new algo I wrote for my scrolling map. It´s smoother, and can be controlled by key for better tests.
The other is an idea I coded for the "splash screen texts" in between game levels. Just an idea for a non expensive solution.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 20, 2017, 05:12:12 PM
UPDATE 1: New algo for the scrolling map.

I´m still soly tasting the waters. But I´m introducing some structures and so on.

Size is about 4k. Memory steady at 3.616

1. Ok, I tried many things and read a lot from you here in the forum. Hard coding the scroll map seems the best way to go I guess. I tried ScrollWindowsEx but I loose control of things (although it´s a lot smoother).

2. I definitely need a better mouse solution, this one doesn´t do and I know why. But it will do for now.
You can use the arrows:
Left/right: move our guy sideways
UP/Down: accelerates/decelerates the map

3. I got rid of all RGB macros since I don´t need them at runtime. I rather got prefixed hex values in a struct. But I think they would be better as const. (is it possible to make a const. struct.?? It bothers me to have all those variables floating around)

4. I´m slowly implementing a gameState control for the game design.

Any feedback will be more than welcome!
Alex


Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 20, 2017, 05:33:11 PM
UPDATE 2: Splash screen prototype

I wrote this as an idea for inter levels splash screens. It emulates someone typewriting, then it fades the text out and turn it into black. I think it´s elegant and minimalistic for such a simple game.

1. Warning: I´m using a 100% free typewriter font. You need to install it to run the prog. I could´ve used AddFontResourceEx/RemoveFontResourceEx but that would temporarily install the font, and I´m not sure if this is consider "ok". So I didn´t, please let me know how to go about this? (font attached in a folder plus copyrights clearance)

2. This is interesting:

qEditor complains about this line:
Quoteinvoke CreateFont, 17,0,0,0,400,0,0,0, ANSI_CHARSET, 0, 0,0,0, ADDR chr$("Sears Tower") ;NOT good in qEditor

RichMasm doesn´t!

However... qEditor is fine with these ones in my other prog:
Quoteinvoke CreateFont,12,0,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
                                           DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT, chr$("Courier New")

What´s happening with this?



3. Can we play mp3 instead of a .wav file? It´s tremendously big for a simple typewriter sound (37kb), unless I really bring the sample rate down. What´s the suggestion?

Cheers
Alex

Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 20, 2017, 05:40:14 PM
Alex,

ADDR chr$("Sears Tower")

This will not work in MASM32, try it without the ADDR as this looks like its a pointer to the pointer that "chr$" returns.

Now I tried your last post, left to right works but a bit sluggish, the forward could be slowed up but I could not get it to run in reverse.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 20, 2017, 05:52:53 PM
Quote from: hutch-- on February 20, 2017, 05:40:14 PM
Alex,

ADDR chr$("Sears Tower")

This will not work in MASM32, try it without the ADDR as this looks like its a pointer to the pointer that "chr$" returns.

Yes! it´s working as you said, cheers.

QuoteNow I tried your last post, left to right works but a bit sluggish,
Possibly 2 things Hutch:
a. I´m incrementing its y coord by 8
b. I´m intentionally not invalidateRect there. I get some memory leak when I do it, I still need to work on this
Could it be this what you meant or something else?
Quote.ELSEIF uMsg == WM_KEYDOWN
               .IF wParam == VK_LEFT
                   add man.x, -8           

              .ELSEIF wParam == VK_RIGHT
                    add man.x, 8
                   
              .ELSEIF  wParam == VK_UP

Quotethe forward could be slowed up but I could not get it to run in reverse.
I´m not allowing it to reverse.  When you reach speed 8 there´s a jump in speed. Same when speed= 2, and 0. It´s me trying to change different variables in there


Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 20, 2017, 06:04:34 PM
I will work on the key code Hutch. But there is this problem with WM_KEYDOWN. There is this auto repeat feature I don´t know how to change or deal with. So KEYDOWN is really unusable as of now:

msdn:
QuoteThe repeat count for the current message. The value is the number of times the keystroke is autorepeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative.

QuoteBecause of the autorepeat feature, more than one WM_KEYDOWN message may be posted before a WM_KEYUP message is posted. The previous key state (bit 30) can be used to determine whether the WM_KEYDOWN message indicates the first down transition or a repeated down transition.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 20, 2017, 06:28:08 PM
Quote from: LordAdef on February 20, 2017, 05:33:11 PM
qEditor complains about this line:
Quoteinvoke CreateFont, 17,0,0,0,400,0,0,0, ANSI_CHARSET, 0, 0,0,0, ADDR chr$("Sears Tower") ;NOT good in qEditor

RichMasm doesn´t!

Alex,
Strictly speaking this is not RichMasm's merit, but rather due to the fact that RM uses HJWasm32 by default. Try to add this under your code:OPT_Assembler ML

and voilà: error A2033:invalid INVOKE argument : 14

One could argue that all assemblers should throw an error here. Of course, your intention is clear: "addr chr$()". But it's incorrect syntax from a MASM point of view. @HJWasm+AsmC teams: what about a little warning?

Re RGB macros, they can be very compact, i.e. they do not add much code. Have a look at this snippet through the eyes of Olly, it uses RGB (original Masm32 macro) and RgbCol() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1331):
include \masm32\MasmBasic\MasmBasic.inc
  Init
  int 3
  RGB 12h, 34h, 56h ; Masm32 macro
  print hex$(eax), 13, 10

  PrintLine Hex$(RgbCol(12h, 34h, 56h)) ; MasmBasic equivalent

  mov eax, 12h
  mov ecx, 34h
  mov edx, 56h
  PrintLine Hex$(RgbCol(eax, ecx, edx))

  mov eax, 12h
  mov ecx, 34h
  mov edx, 56h
  if 0 ; not possible:
RGB eax, ecx, edx
  else ; but this works:
mov eax, RgbCol(eax, ecx, edx)
  endif
  print hex$(eax), 13, 10
  inkey "ok?"
EndOfCode


Even this works, btw:

  PrintLine "Gradual colour change:"
  For_ ecx=0 To 255 Step 11h
      PrintLine Hex$(RgbCol(22h, ecx, 44h))
  Next


Output:Gradual colour change:
00440022
00441122
00442222
00443322
00444422
00445522
00446622
00447722
00448822
00449922
0044AA22
0044BB22
0044CC22
0044DD22
0044EE22
0044FF22


Quote from: LordAdef on February 20, 2017, 06:04:34 PMThere is this auto repeat feature I don´t know how to change or deal with. So KEYDOWN is really unusable as of now:

What exactly is the problem there?
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 21, 2017, 05:41:16 AM
Hi JJ,

I was using the RGB macro. The thing is, there´s no need to waste processor time when I know the colours I need. The code and debugger gets cleaner. What I will chance is forget the colour structure and make them const.

Re Keyboard, I get back to you later today. I need either getKeyboardState or ASync.... (I know getKeyboard.. is slower, so I might try the other one). This is how I implemented my game in C. Although I used the SDL library, the principle worked.



But here is a quicky one:

I decided to clean up my asm file. I created an inc called "stuff.inc" with protos, structs. I also put the Windows shite as a macro so I don´t need to stare at it all the time:

Quote


;------------------- PROTOTYPES ---------------------------------------------------------------------------

    WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
    pLoad   PROTO :DWORD
    pIni    PROTO
    pIniFonts PROTO :DWORD
    pSetGameState   PROTO   :DWORD

;------------------------- STRUCTS ----------------------------------------------------------------------

RGB macro red,green,blue
            xor eax,eax
            mov ah,blue
            shl eax,8
            mov ah,green
            mov al,red
    endm
        ;---------------------
        ;--- STRUCTURES ------
        ;---------------------
        Game STRUCT
               lives    dd  ?
               level    dd  ?
               state    dd  ?
               speed  dd  ?
               dispRect  RECT <>
        Game ENDS
       
        Map  STRUCT
           scroll      dd   ?
      linevstart   dd   ?
      line      dd   ?
      yspace      dd   ?
        Map ENDS
       
        Player STRUCT
               speed      dd  ?
               x          dd  ?
               y          dd  ?
               angle      dd   ?
               tx      dd   ?
               ty      dd   ?
        Player ENDS
   
        Enemy STRUCT
               speed   dd  ?
        Enemy ENDS
   
        Bullet STRUCT
               speed   dd  ?
        Bullet ENDS
       
        Colours STRUCT
              white   dd   ?
              yellow   dd   ?
                 bk      dd   ?
              display   dd   ?
        Colours   ENDS

;------------------- MACROS -----------------------------------------------------------------------------------


MacroDisplay macro
                    ; ------------------ TEMPORARY HERE FOR TESTS ----------------------
                    ; Debug display:
                    invoke TextOut,hdc, 0, 600, chr$("Speed:"), 6      
         invoke TextOut,hdc, 30, 600, str$(gm.speed), 3

                    invoke TextOut,hdc, 0, 620, chr$("line:"), 6      
         invoke TextOut,hdc, 30, 620, str$(map.line), 4
                     
                   ; --------- print DISPLAY ------------------------------------
                    invoke SelectObject, hdc, Font4               ; display labels
                    invoke SetTextColor,hdc, colours.display

                    invoke SetBkMode, hdc, TRANSPARENT
                    invoke TextOut,hdc,10,60, chr$("Level"), 5 ;ADDR Label1, 5
                    invoke TextOut,hdc,10,300, chr$("Lives"), 5 ;ADDR Label1, 5

                    invoke SelectObject, hdc, Font3
                    invoke SetTextColor,hdc, colours.display

                    invoke SetBkMode, hdc, TRANSPARENT         ; display values
                    invoke TextOut,hdc,20,90, str$(gm.level), 1 ;ADDR Label1, 5   
                    invoke TextOut,hdc,20,330, str$(gm.lives), 1 ;ADDR Label1, 5
                    ; -----------------------------------------------------------
    endm
   
    macroWinMain macro
     
       mov   wc.cbSize,SIZEOF WNDCLASSEX
       mov   wc.style, CS_HREDRAW or CS_VREDRAW
       mov   wc.lpfnWndProc, OFFSET WndProc
       mov   wc.cbClsExtra,NULL
       mov   wc.cbWndExtra,NULL
       push  hInst
       pop   wc.hInstance
       mov   wc.hbrBackground,COLOR_WINDOW+2
       mov   wc.lpszMenuName,NULL
       mov   wc.lpszClassName,OFFSET ClassName
       invoke LoadIcon,NULL,IDI_APPLICATION           
       mov    wc.hIcon,eax
       mov    wc.hIconSm,eax
       invoke LoadCursor,NULL,IDC_ARROW               
       mov    wc.hCursor, eax
       invoke RegisterClassEx, addr wc
       invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,WS_OVERLAPPEDWINDOW,\
                                            500,10, 900,850,NULL,NULL,hInst,NULL 
       mov    hwnd,eax
      invoke ShowWindow, hwnd,SW_SHOWNORMAL
       invoke UpdateWindow, hwnd

    endm


The question is.....
Before this move my prog was running steady at 3.610 kb.
After this move I´m getting a steady 1.496 kb.... Where is the remaing kbs?? I´m sure they are somewhere..everything is working as it should
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 21, 2017, 05:48:28 AM
Alex,

I would be inclined to only use the Windows keyboard messages to start and finish the key operations but to get an adjustable repeat rate, I would set up a thread with a timer where you set the repeat rate yourself and trigger the screen movement with your own delay rate.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 21, 2017, 05:54:08 AM
Quote from: hutch-- on February 21, 2017, 05:48:28 AM
Alex,

I would be inclined to only use the Windows keyboard messages to start and finish the key operations but to get an adjustable repeat rate, I would set up a thread with a timer where you set the repeat rate yourself and trigger the screen movement with your own delay rate.

Well, I know I can set more than one timer, but I´m not sure how I could implement that in my actual state of personal development :)

The main issue is windows have this repeat count for KeyDown and apparently it shows it at bit 30. I have no bloody clue how to change that ::)

Hutch, how about this size change in my device manager after I´ve created the inc file. Is this normal?
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 21, 2017, 06:32:54 AM
Hutch. I BLOODY GOT IT. Keys working like a charm now

QuotepKeyEvents    proc   hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

   invoke GetAsyncKeyState, VK_RIGHT
   AND   ax, 8000h
   cmp ax, 32768
   jz Right
   
   invoke GetAsyncKeyState, VK_LEFT
   AND   ax, 8000h
   cmp ax, 32768
   jz Left
   
   invoke GetAsyncKeyState, VK_UP
   AND   ax, 8000h
   cmp ax, 32768
   jz Up
   
   invoke GetAsyncKeyState, VK_DOWN
   AND   ax, 8000h
   cmp ax, 32768
   jz Down
   jmp @F

   Right:
        add man.x, 2 ;8
        jmp @F
   
   Left:
        sub man.x, 2
        jmp @F   
   Up:
       macroSpeedUP
       jmp @F
   Down:
        macroSpeedDown
   @@:
   ret
pKeyEvents endp
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 21, 2017, 07:43:41 AM
 :biggrin:

> Hutch. I BLOODY GOT IT. Keys working like a charm now  :t
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 21, 2017, 08:38:50 AM
Quote from: LordAdef on February 21, 2017, 06:32:54 AMinvoke GetAsyncKeyState, VK_RIGHT
   AND   ax, 8000h
   cmp ax, 32768
   jz Right

invoke GetAsyncKeyState, VK_RIGHT
test ah, ah
js Right


same result ;)
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 21, 2017, 09:49:48 AM
Quoteinvoke GetAsyncKeyState, VK_RIGHT
   AND   ax, 8000h
   cmp ax, 32768
   jz Right

And I thought I was being very clever here, since I pulled this off by myself! Cheers JJ, I updated the code with your suggestion.

I attached the prog updated with the latest suggestions. I also now have a bitmap airplane, check it out!

I took this bitmap code from Iczelion. It´s a first timer here too among a thousand this week.
Just checking: Do I need to keep all of these inside my PAINT loop?

Quote;-------  AIRPLANE -----------------
        invoke CreateCompatibleDC,hdc
        mov    hMemDC,eax
        invoke SelectObject,hMemDC,hBitmap
        invoke GetClientRect,hWnd,addr rect
        invoke BitBlt,hdc, man.x, man.y, rect.right, rect.bottom, hMemDC, 0, 0, SRCPAINT ;SRCCOPY
         invoke DeleteDC,hMemDC
        ;--------------------------------------------------------------------------------------------------------------
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 21, 2017, 11:23:29 AM
You can probably get away with putting the open and close GDI resource code in your startup/exit code but keep an eye on the device context count and also check your memory usage after running the app for a while.
Title: Re: "Hello masm32", not a BOT, new member
Post by: avcaballero on February 21, 2017, 07:20:52 PM
It looks nice :t
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 22, 2017, 11:08:31 AM
thanks Caballero
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on February 22, 2017, 12:32:44 PM
This one works well, just downloaded and tested it and the left right keys navigate the plane with no lag at all.  :t
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 22, 2017, 06:37:26 PM
Quote from: hutch-- on February 22, 2017, 12:32:44 PM
This one works well, just downloaded and tested it and the left right keys navigate the plane with no lag at all.  :t

Nice Hutch!

Well, today I complete a full month as part of the Masm32 community!
I guess you wont get rid of me any soon  :eusa_naughty:

I made some small little cleaning, and put some animation for my airplane. Attached the exe, just for fun.

Cheers, Alex
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on February 22, 2017, 06:58:15 PM
Very cute, compliments :t
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 28, 2017, 07:20:29 PM
Hi guys,

I created another actor for the game, a Bomber. While testing the little guy, I could not make it look right. Its body is transparent although the colour background is fine. Just run the exe and see what I mean (What matters is when inside the map, I left it bleed on the left side on purpose) .

The temp code is this one below (it´s just for test):

Quote;-------------- TESTING ONLY! --------------
          mov eax, map.line
           add eax, edi
         Switch eax   
         Case 470               ;this is line
                 mov bomber.y, ebx
         Endsw
           invoke   SetTextColor,hdc,  colBOMBER
           invoke BitBlt, hdc, bomber.x, bomber.y, 36, 35, hMemDCbomber, 0, bomber.frmy, SRCPAINT ;

The file for the Bomber is "Bomber.bmp", 1 bit.

Any hint on how to work this out?
Cheers!

ps: For those who don´t remember River Raid for Atari, I found this link:
https://www.youtube.com/watch?v=kNXQYH-xTK8 (https://www.youtube.com/watch?v=kNXQYH-xTK8)

What I´m doing is a loose recreation of River Raid, more of a inspiration in fact. As you can see, there are these Bombers in the original game, but they don´t follow the map and run horizontally. I changed that.


ps2: Some small changes: Windows is not resizable anymore, colours are constants
Title: Re: "Hello masm32", not a BOT, new member
Post by: avcaballero on February 28, 2017, 07:39:51 PM
That's nice. I guess that if you fly outside the river you will lose.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on February 28, 2017, 07:43:07 PM
Exactly Caballero!

I still need to write the collision detection algorithm. There is where the fun is!
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on March 01, 2017, 12:56:21 PM
Update on the transparency & bombers:

I managed to make it to work, but it´s a very expensive solution and it´s bloating my exe file... I really need someone to suggest me a cheaper solution, please.

I´m using two bmp: 1 bit one and the other is 4 bits (it doesn´t work with 2 1bits)
I´m using 2 bitblt lines (attached as separate files in the zip):

Quoteinvoke   SetTextColor,hdc,  colBOMBER
           invoke BitBlt, hdc, bomber.x, bomber.y, 36, 35, hMaskDC, 0, bomber.frmy, SRCAND
           invoke BitBlt, hdc, bomber.x, bomber.y, 36, 35, hMemDCbomber, 0, bomber.frmy, SRCPAINT

So, a veeery expensive solution for a small detail.

As a bonus, due to the FANTASTIC Switch/case in MASM I put 5 little guys flying for you.

Quote;-------------- TESTING ONLY! --------------
          mov eax, map.line
           add eax, edi
         Switch eax   
         Case 450, 440, 430, 400, 390            ;this is line. 5 planes at given lines
                 mov bomber.y, ebx
         Endsw

Any help is welcomed
Cheers Alex

ps: asm and Richmasm files included.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on March 01, 2017, 07:39:39 PM
Quote from: LordAdef on March 01, 2017, 12:56:21 PM
I´m using 2 bitblt lines (attached as separate files in the zip):
...
So, a veeery expensive solution for a small detail.

Hi Alex,

Test this:;xxxxxxxxxxxxxxxxxxxxxxxxx
;   ASCii Raid. game foundation
;xxxxxxxxxxxxxxxxxxxxxxxxx
include \masm32\MasmBasic\MasmBasic.inc
; include \masm32\include\masm32rt.inc
include stuff.inc ;protos, structs, macros
...
      NanoTimer()
      invoke BitBlt, hdc, bomber.x, bomber.y, 36, 35, hMaskDC, 0, bomber.frmy, SRCAND
      invoke BitBlt, hdc, bomber.x, bomber.y, 36, 35, hMemDCbomber, 0, bomber.frmy, SRCPAINT
      Print Str$("%i us ", NanoTimer(us))


The animation will not work properly, but it's just for showing how expensive your solution really is 8)
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on March 02, 2017, 07:15:25 PM
QuoteThe animation will not work properly, but it's just for showing how expensive your solution really is 8)

Hi JJ,

This is what I´ve got from 2 scenarios:

1st line:
Quoteinvoke BitBlt, hdc, bomber.x, bomber.y, 36, 35, hBomberDC, 0, bomber.frmy, SRCPAINT
2nd line:
Quoteinvoke BitBlt, hdc, bomber.x, bomber.y, 36, 35, hMaskDC, 0, bomber.frmy, SRCAND
invoke BitBlt, hdc, bomber.x, bomber.y, 36, 35, hBomberDC, 0, bomber.frmy, SRCPAINT

Quote5  us 9 us 24 us 10 us 46 us 24 us 21 us 21 us 18 us 38 us 36 us 21 us 23 us 20 us 19 us 19 us 28 us 35 us 23 us 22 us 22 us 22 us 20 us 15 us 27 us 23 us 21 us     Average: 21
23 us 9 us 82 us 7  us 30 us 27 us 26 us 33 us 42 us 29 us 25 us 24 us 21 us 33 us 29 us 25 us 54 us 27 us 23 us 36 us 27 us 24 us 24 us 25 us 24 us 25 us 24 us     Average: 28

Interesting test. And it´s good because I was lacking a way to time my code. I will now be using your macros to time it further.

Apart from any performance issue, I am actually suffering with the extra  2.57kb I´m having to add to my payload (on top of the 1bit 902 bytes for the same actor).

Do you think this is a nice solution then?

Disclaimer:
It´s all you guys´s fault, I´m turning into this miserable programmer crying for every byte added, and every tick lost :dazzled:

I blame you and Hutch!!!  :badgrin:
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on March 02, 2017, 07:22:12 PM
 :biggrin:

> I blame you and Hutch!!!

If in doubt, choose speed over size.
If not in doubt, choose speed over size.
If all else fails, choose speed over size.
Don't care what others do, choose speed over size.

And if none of that works, make it go fast !!!!
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on March 02, 2017, 07:48:00 PM
Quote from: hutch-- on March 02, 2017, 07:22:12 PM
:biggrin:

If in doubt, choose speed over size.
If not in doubt, choose speed over size.
If all else fails, choose speed over size.
Don't care what others do, choose speed over size.

And if none of that works, make it go fast !!!!

noted Hutch!
That's why I'm still trying to figure out a way to optimize this bit, but can't find a solution. The small little losses will be summing into a performance drawback. That's why I'm going slowly, and not pilling up code.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on March 02, 2017, 09:17:04 PM
Quote from: LordAdef on March 02, 2017, 07:15:25 PM
Average: 28
Interesting test.

Indeed: 28 microseconds. If you consider that a smooth video display requires around 20 frames per second, then a single frame needs 50 milliseconds. So you are a factor 2000 faster than required. There is no performance problem, your solution with the two bitmaps is the right one :t
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on March 19, 2017, 07:05:02 PM
Hello my friends!

I was working on the map´s RLE. I managed to compress it from 90kb to 2.485 bytes.
The code is not optimized and I was really lazy in many places, but I really wanted it to do its job asap.

I know I could´ve used some macros (like "cmpmem" and many others) that would´ve made my life easier. But I chose to do it all by myself and learn from it. 

The byte data looks like this:
Quote67      -15     0       0       0       0       67      -16     0    66      -17    65      -17     64      -18     63      -19     61      -21 .....

That´s the output:
Quote== COMPRESSING FILE ==
1. Adding dwords from orig. file
2. filtering chars
3. parsing
4. checking for equal lines and building Flag array


Flags array:


01111010000000000010000000000000000000000000000001001000001111100011111111110010
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000101110000000000000000000000000000000000000000000000000000000000000000000
00001000000000000000000000000000000000000000000010000000000110000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000001001
00100000100000001001100010011000110011111111111001000111111000010111100010110010


5. Building final array
6. done.


=============== REPORT ================

file format:[dd Orig.Size][dd lineCount][dd LineLenght][data:BYTE @sp@-sp ?]



Original size= 89997
New size=  2485
Number of lines= 558
Lengh of line= 159
Equal Lines found= 71

Done...

that list of 0/1s is my lazy way to optimize repeated lines.

Again, it needs a lot of cleaning up, but it works.
RichMasm and Asm files attached.

A curiosity: qEditor complained about "print str$(al)". I used print str$(eax) instead.

Now I have to make it read it back.

Last but not least: I ran some speed tests and what I got suggests .If macro is slower than the Switch/case macro. Is there a common sense on this?

.IF vs Case vs Case_:


Quote.IF    564   241   237   349   273   277   410   193   277   375   
Case 188   245   183   205   162   163   183   161   155   165
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on March 19, 2017, 07:55:39 PM
Quote from: LordAdef on March 19, 2017, 07:05:02 PMA curiosity: qEditor complained about "print str$(al)". I used print str$(eax) instead.

That is not qEditor's fault. The Masm32 str$() is just less flexible than Str$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186).

Quote.If macro is slower than the Switch/case macro. Is there a common sense on this?

There is no consensus but instead, with forum search (http://masm32.com/board/index.php?action=search;advanced;search=) for switch timings you can find long threads like this one (http://masm32.com/board/index.php?topic=5539.msg59193#msg59193) :P

Nice work btw :t

If you have many identical lines, sorting them before encoding might be interesting.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on March 19, 2017, 08:26:48 PM
Thanks JJ,

QuoteThat is not qEditor's fault. The Masm32 str$() is just less flexible than Str$().
I´m sure it isn´t. But it must be something between ML.exe and JWasm. I used the masm32rt to built it.

QuoteIf you have many identical lines, sorting them before encoding might be interesting.

I thought of that, and it would be a lot easier. This map has 71 repeated lines, within 558 lines with 159 chars/line. My reasoning was that doing it afterwards (although more complicated in the logic) would be shorter faster.
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on March 19, 2017, 08:59:44 PM
Alex,

The "str$()" macro in MASM32 is specifically for DWORD values, basic emulation and assembler are not the same thing. To use the str$() macro on smaller values you use MOVZX to make it the right size.
Title: Re: "Hello masm32", not a BOT, new member
Post by: mineiro on March 20, 2017, 01:00:09 AM
Hello sir LordAdef;
we have different instructions to compare data, default is 'cmp', but if you are comparing if something is zero, you can use logical 'or', or 'test', or by some assumptions use dec or sub, ... . These instructions can do same thing but how much efficient is to be measure.

I consider code below an ugly code because use a lot of data and little code, one to one byte relation.
;========== FILTER UNWANTED CHARS ====================
;I don't have assembled, can appear sintax errors
printf (" 2. filtering chars\n")
mov ecx, tLen ;.if tLen == 0, abort
or ecx,ecx ;test ecx,ecx?
jz done
push esi
filter:
movzx eax,[esi] ;load a byte data from source
movzx eax,[eax + mytable] ;compute data
or eax,eax ;.if data == 0 ignore
jz ignore_this_data
mov [esi],al ;insert transformed data
ignore_this_data:
inc esi ;next data
dec ecx ;tLen-1
jnz filter
pop esi
done:


.data
align 16
mytable label dword ;byte to byte relation
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h," ",00h,00h

db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db "@",00h,"@",00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h

db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h

db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
.code

I don't have tried to optimize this code, maybe can use cmovxx instructions, ... , I only posted this code to show a way to try to avoid many comparisions.
If you include others signs like "{","}","(",")", so you only need change the byte relation on data table instead of create more code with comparisions.

This tabled code supposed reach a constant time execution, while when inserting compares the execution time changes at each insertion of new signs. The tabled way is usefull too if you like to do your program portable to other chips like microcontrollers. Imaginate a table like hexstring_to_hex, on pc we can just 'mov' to convert and on others chips too, but if there so much code done to PC, will get harder to port that code to others processors/microcontrolers. Well, I'm getting offtopic, "the good, the bad and the ugly" theme song.

edited after: removed an  unecessary push instruction.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on March 20, 2017, 01:33:23 PM
Hi Mineiro, my dear fellow country man,

Nice to see you here!

Quoteprintf (" 2. filtering chars\n")
          xor edi, edi      
     filter:
           movzx   ebx, BYTE Ptr  [esi + edi]
      Switch ebx
      Case '='                           ; = is nothing, for tests only         
         mov BYTE Ptr  [esi + edi], " "         
      Case 60, 62                        ; <  > are bombers signs
         mov BYTE Ptr  [esi + edi], '@'   
      Endsw

   add    edi, 1   
          cmp   edi, tLen
          jnz     filter

I see you are referring to this session of code. I´ll study your example more carefully and learn from it. But in my case there is no need for a Look up table. The chars to filter are minimum in quantity.

Basically, I´m using the base map to set my game level design and so forth. these marks need to be removed. As an example, I´m marking lines with ">" where my bombers should be set (check out my last exe for the game for the bombers).

">" as a bomber:
Quote@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

All that filtering session is doing is checking for these isolated symbols and change them back to the bk @ one.

I might have not understood you well, please forgive me if I did. I thought a test case should be quite enough for the task
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on March 20, 2017, 02:00:25 PM
Forgot to say, thanks for the "or"/"test" tip when comparing to 0.

And by the way, in my proggy I´m checking the zero flag very often:

Quotecmp bl, 0
   js Negative
   jz Zero
   jns Positive

I got away with "cmp bl, 0". Should "test" be a better one then? I guess the answer is ...yes..?


edit: Self correction: AND does the job nicely
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on March 20, 2017, 08:08:24 PM
Quote from: LordAdef on March 20, 2017, 02:00:25 PM00
cmp bl, 0
js Negative
jz Zero
jns Positive
print "this is the 4t option", 13, 10
;)


Here is a nice one, the shr eax, 1 is Copyright DednDave:
  lea edi, msg
  .While 1
xor eax, eax
invoke GetMessage, edi, eax, eax, eax
inc eax
shr eax, 1
.Break .if Zero? ; 0 (OK) or -1 (error)
invoke TranslateMessage, edi
invoke DispatchMessage, edi
  .Endw
Title: Re: "Hello masm32", not a BOT, new member
Post by: dedndave on March 20, 2017, 10:05:11 PM
hardly a copyright - lol

but, he won't understand the advantage until he has a better understading of the full instruction set

INC EAX is a single-byte instruction, typically taking 1 clock cycle
SHR EAX,1 is a two-byte instruction, also 1 clock
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on March 20, 2017, 10:25:59 PM
Don't worry, Alex is learning very quickly :P

The clock cycles hardly matter in a GetMessage loop, but it's an elegant way to test for 0 and -1 simultaneously, that's why I posted it here.

include \masm32\include\masm32rt.inc ; plain Masm32

.code
start:
  mov ebx, -3
  .Repeat
print str$(ebx), 9
mov eax, ebx
inc eax
shr eax, 1
.if Zero?
print "ZERO", 13, 10
.else
print "non-zero", 13, 10
.endif
inc ebx
  .Until sdword ptr ebx>2
  inkey "ok?"
  exit
end start


Output:
-3      non-zero
-2      non-zero
-1      ZERO
0       ZERO
1       non-zero
2       non-zero
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on March 20, 2017, 11:20:43 PM
This is still my preferred message loop in 32 bit code when you are not processing keystrokes.

MsgLoop proc

    LOCAL msg:MSG

    push ebx
    lea ebx, msg
    jmp getmsg

  msgloop:
    invoke TranslateMessage, ebx
    invoke DispatchMessage,  ebx
  getmsg:
    invoke GetMessage,ebx,0,0,0
    test eax, eax
    jnz msgloop

    pop ebx
    ret

MsgLoop endp


64 bit version does not look much different.

msgloop proc

    LOCAL msg    :MSG
    LOCAL pmsg   :QWORD

    mov pmsg, ptr$(msg)                     ; get the msg structure address
    jmp gmsg                                ; jump directly to GetMessage()

  mloop:
    invoke TranslateMessage,pmsg
    invoke DispatchMessage,pmsg
  gmsg:
    test rax, rv(GetMessage,pmsg,0,0,0)     ; loop until GetMessage returns zero
    jnz mloop

    ret

msgloop endp
Title: Re: "Hello masm32", not a BOT, new member
Post by: mineiro on March 21, 2017, 04:17:48 AM
Hello sir LordAdef;
I read some of your sources and look good man, that river raid make me feel nostalgic time. Nice. I perceive that you have programming knowledge, you modeled your data so rle works fine.
On pass 3 you can read a dword data and compare with next dword data, so you need add 4 as displacement, and when they differs you do on byte way to normalize.

edited: I forgot to say, I tested yours examples on wine under linux and worked fine.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on March 21, 2017, 05:45:00 AM
Hi Mineiro!!

Thanks a lot!

QuoteI read some of your sources and look good man, that river raid make me feel nostalgic time.

Yes, River Raid was a fantastic game. In order to have a goal, I chose it as a project.

QuoteNice. I perceive that you have programming knowledge, you modeled your data so rle works fine

I do in fact, although I´ve never had a formal education. As most of us, I started with good old BASIC, then I moved onto a couple of other things. I must admit I feel like I wasted my time! Assembly was always something painted as a "don´t touch it" thing. I am in love and I think I will stuck with asm for good.

QuoteOn pass 3 you can read a dword data and compare with next dword data
This is actually a great idea!

I´m currently writing the decompression code to unroll my map back. Almost done! This is the one I need to be fast, since it´s going to be working at runtime in the proggy.

I´m doing it slow but steady. I want to finish this game at all costs.

Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on March 30, 2017, 06:29:54 PM
Hey guys,

After your tips in the other thread, I enclosed the prog now with the rle working fine and faster (decomp.inc, decomp.asm).

Richmasm and Asm files included, although qEditor (not its fault, mine for sure) complaint when building:
QuoteC:\masm32\AFprojs\09_game_test_03\Main.asm(64) : warning A4014: instructions and initialized data not supported in BSS segments
...
LINK : fatal error LNK1181: cannot open input file "C:\masm32\AFprojs\09_game_test_03\Main.obj"

Mineiro, I tried to make a struct for the header (mainly because there are more things to go in there). It slowed it down a bit, I kept it as it was.

I´m also now using "Alloc" in the procedure (sending the address to MapPtr  dd  ?).

Next, I´m creating an array of pointers to hold the line addresses. That will speed up my paint code and also give me freedom to do my next step with this thing.

Cheers, Alex
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on March 30, 2017, 07:13:01 PM
Works fine indeed :t

I wonder why it throws a Warning A4184: Instructions and initialized data not supported in BSS segments on
gm  Game    <> ::)
Title: Re: "Hello masm32", not a BOT, new member
Post by: dedndave on March 31, 2017, 04:59:38 AM
possibly either the symbol "gm" or "Game" (or both) are defined elsewhere ?
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on March 31, 2017, 06:18:49 AM
Hey, I got some interesting update on this, and I think I found a bug in qEditor and that´s why it´s not building.

1. Decomp????

Yep, my bad. I left a line of code of this old variable. Here it is the culprit:
Quotemov   edi, offset Decomp   ====> The little persistent bastard is here!
   mov   esi, InputFile(string)
          mov   tLen, ecx
         
          ; allocate dest. memory
          mov MapPtr, alloc ( DWORD Ptr [esi])   ====> It was replaced by this fellow
          mov edi, MapPtr

2. gm Game <>:
Quote


        Game STRUCT
               lives          dd  ?
               level          dd  ?
               state       dd  ?
               speed        dd  ?
               kills      dd    ?
               mapRect   RECT   <>
               dispRect     RECT <>
               bomber   dd   30   dup(Bomber)   <==== HERE. Bomber is a uninitialized struct too. 
               enemies   dd   60   dup(?)   
        Game ENDS

3. qEditor:
Quote
LINK : fatal error LNK1181: cannot open input file "C:\masm32\AFprojs\09_game_test_03\Main.obj"
Link error
=> It doesn´t build when you "Windows Explorer->Main.asm->rightClick->open in qEditor"
   => It builds fine when you open the file from within qEditor
   Please try and replicate this issue, so to confirm it to Hutch
Title: Re: "Hello masm32", not a BOT, new member
Post by: dedndave on March 31, 2017, 06:47:22 AM
i'm a little rusty, but i think it should be...

               bomber   dd   30   dup(Bomber<>)

something like that
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on March 31, 2017, 06:57:07 AM
Yes, thanks!
Did you replicate the qEditor thing?
Title: Re: "Hello masm32", not a BOT, new member
Post by: dedndave on March 31, 2017, 07:25:48 AM
i don't use qEditor - lol
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on March 31, 2017, 04:36:34 PM
Quote from: LordAdef on March 31, 2017, 06:18:49 AM=> It builds fine when you open the file from within qEditor

Builds fine with RichMasm, and builds OK when I drag Main.asm over qEditor.exe - but qEditor ignores the resources for some reason.
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on April 01, 2017, 06:53:22 PM
The default MASM32 console build requires the resource script to be called RSRC.RC. Added a "makeit.bat" and renamed the RC script and it builds as normal in QE using the MASM32 default.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 24, 2017, 10:43:04 PM
Hi guys,

It´s been a while I don´t update this project, so here I am.

It´s not optimized "at all". There are many decouplings to fix and CPU is running hot for now. But all in all this begins to look like a game.

1. My rle is working in all its glory (thanks everyone for helping optimizing it)
2. I made some game management already, so it loads levels, reset level when we die and so forth...
3. Fuel is working now (not refueling)
4. There are 3 temporary maps so I can test things
5. Made a experimental explosion. Try and suicide, and check it out. It´s quite nice :D
6. Maps are way larger now. I decompress them, but in fact I use an array of pointers. This way I´m doubling its lenght, but reversing it in the second half. More content for the same space
7. Collision Detection is in place, but in pure bare bones, only for development.
8. Made some "god mode" keys for development:
    number 1: resume game
    number 2: pause game
    number 4: load next level
   
9. arrows work as usual, however I limited to only 2 speeds for now.
10. Built with RichMasm. This time I didn´t try on qEditor, but I know it gives it errors. I didn´t try to fix them though
Cheers, Alex


   
Title: Re: "Hello masm32", not a BOT, new member
Post by: Siekmanski on April 24, 2017, 11:27:56 PM
Hi LordAdef,

The arrow keys are not responding.

EDIT: it works now, had to press 1 first.  :t
Title: Re: "Hello masm32", not a BOT, new member
Post by: HSE on April 24, 2017, 11:29:53 PM
Just a fixed map, with the airplane and a copyright symbold instead the bombarder of previous versions.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 24, 2017, 11:33:36 PM
try number 1 to resume game, it starts in pause mode

press 2 and it pauses.
if you press 4 "while" running, it loads the next level
Title: Re: "Hello masm32", not a BOT, new member
Post by: HSE on April 25, 2017, 12:11:38 AM
Beautifull ... crash using 1

The code is not ML compatible. For this I used AsmC:

004014F5 >  55              PUSH EBP
004014F6    8BEC            MOV EBP, ESP
004014F8    A1 8CD14000     MOV EAX, DWORD PTR DS:[man]
004014FD    83E8 62         SUB EAX, 62
00401500    BB 05000000     MOV EBX, 5
00401505    F7F3            DIV EBX                <---   CRASH
00401507    8B3D 78544000   MOV EDI, DWORD PTR DS:[405478]
0040150D    83C7 3C         ADD EDI, 3C
00401510    8B34BD 8C544000 MOV ESI, DWORD PTR DS:[EDI*4+40548C]
00401517    03F0            ADD ESI, EAX
00401519    803E 40         CMP BYTE PTR DS:[ESI], 40
0040151C    74 02           JE SHORT Main_v8_.00401520
0040151E    EB 08           JMP SHORT Main_v8_.00401528
00401520    FF75 08         PUSH DWORD PTR SS:[EBP+8]
00401523    E8 E1090000     CALL Main_v8_.pDead
00401528    5D              POP EBP
00401529    C2 0400         RETN 4

Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 25, 2017, 04:23:55 AM
JWasm.
I'll check it out for compatibility. Cheers
Title: Re: "Hello masm32", not a BOT, new member
Post by: avcaballero on April 25, 2017, 04:56:31 AM
Wow, how fast is it. Only one thing, if you press to the left or to the right, the plane keep on facing to there though you release the key.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 25, 2017, 08:11:52 PM
Quote from: caballero on April 25, 2017, 04:56:31 AM
Wow, how fast is it. Only one thing, if you press to the left or to the right, the plane keep on facing to there though you release the key.

Hi Caballero! wow, this is totally unexpected... It's a simple KeyUp message that brings the plane back to the right position... I'm turning the pc on and see what's happening. Please follow me on this.

Anyone else not having the plane back to straight position?
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 25, 2017, 08:30:37 PM
Works fine here, no problems with these keys. You might write in big letters "press 1 to start the game", it took me a while to find that out :P

Quote from: LordAdef on April 24, 2017, 10:43:04 PMTry and suicide, and check it out. It´s quite nice :D

Try posting such a phrase in a forum for kids & education, the mums will eat you alive :badgrin:
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 25, 2017, 08:34:31 PM
QuoteTry posting such a phrase in a forum for kids & education, the mums will eat you alive :badgrin:

hahaha.. you are right! Out of context this line sounds indeed quite odd
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 25, 2017, 10:29:11 PM
HI there,

A quick update:
1. It now shows "Press 1 to start"
2. Caballero had and issue with the plane not returning to straight position. This should be fixed now (I hope  :badgrin:)

Caballero, let me know?

It´s still not currently ml compatible. I´ll be working on that. Nevertheless, I placed the main source code as an asm file for reference only.
Title: Re: "Hello masm32", not a BOT, new member
Post by: Siekmanski on April 25, 2017, 10:30:24 PM
Works fine here, also no problems with these keys.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 25, 2017, 11:04:59 PM
Quote from: Siekmanski on April 25, 2017, 10:30:24 PM
Works fine here, also no problems with these keys.

Thanks Marinus!
Btw, sometime in the far future I will need to add music... I am surely bothering you when the time comes, I'd love some contribution from you.

I already have a friend from the place I work that will be doing the graphics for the final build
Title: Re: "Hello masm32", not a BOT, new member
Post by: avcaballero on April 25, 2017, 11:19:45 PM
It works fine now :)
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 25, 2017, 11:22:48 PM
Quote from: caballero on April 25, 2017, 11:19:45 PM
It works fine now :)
Aham!! Thanks amigo
Title: Re: "Hello masm32", not a BOT, new member
Post by: HSE on April 25, 2017, 11:55:19 PM
Commenting pColisionDetection work without problem!
Title: Re: "Hello masm32", not a BOT, new member
Post by: guga on April 26, 2017, 12:11:23 AM
Not working on XP (crashes after pressing 1)
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 26, 2017, 01:51:08 AM
Quote from: guga on April 26, 2017, 12:11:23 AM
Not working on XP (crashes after pressing 1)

sub eax, 98
cdq  ; and it works in XP...
m2m ebx, 5
div ebx ; eax is char count in line
Title: Re: "Hello masm32", not a BOT, new member
Post by: HSE on April 26, 2017, 02:24:28 AM
 Perfect JJ :t
Title: Re: "Hello masm32", not a BOT, new member
Post by: Siekmanski on April 26, 2017, 03:52:32 AM
Quote from: LordAdef on April 25, 2017, 11:04:59 PM

Thanks Marinus!
Btw, sometime in the far future I will need to add music... I am surely bothering you when the time comes, I'd love some contribution from you.

I already have a friend from the place I work that will be doing the graphics for the final build

I hope you don't mean to compose music, that will be a total disaster.  :lol:
I think you meant some music replay routines.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 26, 2017, 07:46:31 AM
QuoteI hope you don't mean to compose music, that will be a total disaster.  :lol:
I think you meant some music replay routines.

Don´t worry, I can handle the music. I´m a music composer (or I think I am)
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 27, 2017, 01:59:17 AM
Quotesub eax, 98
   cdq  ; and it works in XP...
   m2m ebx, 5
   div ebx      

Thanks for that JJ.
So XP complained and needed sign extension. Would you tell me why win7 was ok while XP was not?

One more question if I may: I thought I should be fine as I was doing unsigned values. Should I always CWB/CWD/CQD to avoid such conflicts?

And thanks everyone for the help!!
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 27, 2017, 03:17:02 AM
Hi,

So, I was checking the ml compatibility and found only 2 places where things go bad in ml:

1. In main.asm (Line 431), the IF statement within a Switch-Case:
Quotemain.asm(434) : error A2206: missing operator in expression
main.asm(437) : error A2206: missing operator in expression
main.asm(439) : error A2206: missing operator in expression
main.asm(440) : error A2206: missing operator in expression

The problematic code for ml (comment and ther errors are gone):
QuoteSwitch gm.state
      Case PLAYLEVEL, STANDBY
               ;-------------- GODs MODE KEYS -------------
             .IF  wParam == 0x31              ; key "1"      start timers
                mov gm.state, PLAYLEVEL
                invoke pSetTimer_All, hWnd         
             .ELSEIF wParam == 0x32         ; key "2"      stop timers
                invoke pKillTimer_All, hWnd   
             .ELSEIF wParam == 0x33         ; key "3"      empty
             .ELSEIF wParam == 0x34         ; key "4"      load new level
              m2m gm.state, LEVELDONE
           .ENDIF
          endsw

In Decomp.inc, these const:
Quotedecomp.inc(46) : error A2042: statement too complex
decomp.inc(51) : error A2008: syntax error : integer
decomp.asm(175) : error A2006: undefined symbol : statBlockage1
decomp.asm(175) : error A2114: INVOKE argument type mismatch : argument : 2
decomp.asm(174) : error A2006: undefined symbol : statBlockage1
decomp.asm(184) : error A2006: undefined symbol : statBlockage1

(commenting, leaving few vars and you get no errors.)
QuotestatMines1   dd   137782, 138577, 138899, 141944, 142110, 151425, 151919, 152373, 152569, 153499,\
            153974, 154131, 154289, 190342, 192719, 192878, 194344, 194345
            
statBlockage1 dd    186986, 186987, 186988, 186989, 186990, 186991, 186992, 186993, 186994, 186995,\
            186996, 186997, 186998, 186999, 187000, 187001, 187002, 187003, 187004, 187005,\
            187006, 187007, 187008, 187009, 187010, 187011, 187012, 187013, 187014, 187015,\
            187016, 187146, 187147, 187148, 187149, 187150, 187151, 187152, 187153, 187154,\
            187155, 187156, 187157, 187158, 187159, 187160, 187161, 187162, 187163, 187164,\
            187165, 187166, 187167, 187168, 187169, 187170, 187171, 187172, 187173, 187174,\
            187175, 187176

statFuel2      dd   8867, 48448, 59781, 65220, 68562, 72358, 75612, 81510, 87119, 89510

statMines2      dd      1000
statBlockage2   dd      1000

In short, I´m ml compatible except from these 2 things: the .IF statement and those variables declarations.
HJWasm is ok and gives me no warnings.

ps: makeit.bat in zip was kindly provided by Hutch
Title: Re: "Hello masm32", not a BOT, new member
Post by: nidud on April 27, 2017, 04:15:05 AM
deleted
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 27, 2017, 04:16:01 AM
Quote from: LordAdef on April 27, 2017, 01:59:17 AMSo XP complained and needed sign extension. Would you tell me why win7 was ok while XP was not?

edx is undefined when you return from whatever WinAPI call. And the API changes with every Windows version. Not the documented behaviour, of course - that is remarkably stable. But ecx and edx can contain any value (MB preserves ecx, though).

So if you got, by accident, 0 in edx when running it in Win7, the div ebx works fine. But XP has a different edx, and bang :(

The solution is simple: every div MUST be preceded by cdq, except for the rare case when you really want to divide a edx::eax QWORD.

@nidud: you were almost one minute faster ;)

Caution with xor edx, edx: This assumes that eax is positive; OK most of the time, but with idiv you get unexpected results:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  mov eax, -111
  xor edx, edx
  mov ecx, 3
  idiv ecx
  deb 4, "result", eax

  mov eax, -111
  cdq
  mov ecx, 3
  idiv ecx
  deb 4, "result", eax
 
  Inkey
EndOfCode


Output:
result  eax             1431655728
result  eax             -37


Besides, cdq is one byte shorter than xor edx, edx ;)
Title: Re: "Hello masm32", not a BOT, new member
Post by: HSE on April 27, 2017, 08:45:05 AM
I'm thinking gm.state is the problem because ml need OPTION DOTNAME to allow that point. I can't test it, but now is working perfect with others assemblers. 
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 27, 2017, 09:17:03 AM
Dots are OK for structures. The problem was elsewhere:
- ML has a maximum line length
- ML does not support 0x12 syntax

Attached a slightly corrected version.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 27, 2017, 08:36:10 PM
Thanks HSE and JJ,

Yep, dot notation is fine. I´ve always tested for ml compatibility and from time to time I bump into something. But dot notation has been there for a long time, ml was fine with that.

In fact, I find this compatibility thing quite instructive. I´m using RichMasm/HJWasm, but I´m trying to keep the compatibility so I can share the code here in the forum.

Not meaning to start a war here, but I notice JWasm is more tolerant in many places, such as this 0x32 notation and the line limit I crossed and JJ pinpointed. But they are close enough not to be a big deal.

I´m not sure if there is a feature comparison available. That would be interesting.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 27, 2017, 09:36:23 PM
Quote from: LordAdef on April 27, 2017, 08:36:10 PMI´m not sure if there is a feature comparison available.

Well, kind of (http://www.masmforum.com/board/index.php?topic=9835.0) :P

For MasmBasic fans, here a special feature of ML:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  mov esi, Chr$("This is a hello World string")
  xor ecx, ecx
  xor edx, edx
  mov eax, [ecx+edx+esi+10]      ; three register addressing!
  push 0
  push eax
  deb 1, "Test", $esp
  pop edx
  pop eax
EndOfCode

OPT_Assembler ML  ; use Microsoft MASM


Note you must force ML because HJWasm is not yet enabled for three register addressing mode (Habran and Johnsa are working on it).

Here is the 64-bit version:include \Masm32\MasmBasic\Res\JBasic.inc
.data
buffer db "Just a test", 0
Init ; OPT_64 1 ; 64 bit assembly
  PrintLine Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format")
  mov rsi, Chr$("This is a hello World string")
  xor ecx, ecx
  xor edx, edx
  mov rax, [rcx+rdx+rsi+10]      ; three register addressing!
  lea rdx, buffer
  usedeb=1
  mov [rdx], rax
  deb 1, "Test", $rdx
EndOfCode

OPT_Assembler ML  ; use the latest and best version of Microsoft MASM


Output:
This code was assembled with ml64 in 64-bit format
Test    $rdx    hello Woest
Title: Re: "Hello masm32", not a BOT, new member
Post by: nidud on April 27, 2017, 11:08:51 PM
deleted
Title: Re: "Hello masm32", not a BOT, new member
Post by: nidud on April 27, 2017, 11:12:49 PM
deleted
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 27, 2017, 11:27:37 PM
Quote from: nidud on April 27, 2017, 11:12:49 PM
hello.asm(20) : error A2030: multiple index registers not allowed

Yes, ML 6.14 and 6.15 throw errors. Microsoft introduced this feature in ML version 8.0 and higher. As my 64-bit example above demonstrates, it builds fine in ML64 (a bit slow, perhaps - 15 seconds), even with version 14:Microsoft (R) Macro Assembler (x64) Version 14.00.24210.0
Copyright (C) Microsoft Corporation.  All rights reserved.

*** Link  Skel_GccVc.obj  using polink, sub CONSOLE /entry:start- no resources ***

Creating object: Tmp_File.exp
Creating library: Tmp_File.lib

***  build all took 15522 ms  ***


Rumours say that Intel and AMD are not happy that M$ allows coders to use this feature 8)
Title: Re: "Hello masm32", not a BOT, new member
Post by: nidud on April 28, 2017, 12:07:21 AM
deleted
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 28, 2017, 01:16:31 AM
> mov eax, [ebx+eax+ecx+edx+esi+10]

Yep, that is the right spirit :t

Let's push the cpu to its limits:
  lea rdx, [rcx+rdx+rsi+r8+r9+r10+r11+r12+10]      ; eight register addressing!

Works fine, and builds in less than fifteen seconds:Microsoft (R) Macro Assembler (x64) Version 14.00.24210.0
Copyright (C) Microsoft Corporation.  All rights reserved.


*** Link  SkelMbEmpty.obj  using polink, sub CONSOLE /entry:start- no resources ***

Creating object: Tmp_File.exp
Creating library: Tmp_File.lib

***  build all took 14992 ms  ***


Title: Re: "Hello masm32", not a BOT, new member
Post by: nidud on April 28, 2017, 01:41:39 AM
deleted
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 28, 2017, 02:17:06 AM
I am sure johnsa and habran are aware of their responsibilities. These new Microsoft features must be implemented asap 8)

[ok ok, this is The Campus, therefore, message to all n00bs readings this: do not believe everything that is written on this forum! Most of us are human beings, we are stupid or ignorant at times, and we see it as our moral obligation to pull your legs. Bashing Micros**t for their incredible bugs is our responsibility, too, and we take that very seriously :eusa_boohoo:]
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on April 28, 2017, 02:25:05 AM
 :biggrin:

You know the magic MASM rule, its not a bug, its a feature you need to understand. Unless Intel have sneaked an undocumented capacity that nobody knew about,multiple index's don't have a matching opcode so they don't fly. RE : MASM error checking, it is more often than not unintelligible nonsense, its a tool written for people who know NOT to try and invent opcodes of their own. If they do they get garbage on the screen.

MASM has always had the answer to fast reliable code, write it with no errors and it will run properly, if not go back and learn how to write code with no errors.  :P
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 28, 2017, 09:01:13 AM
Quotelea rdx, [rcx+rdx+rsi+r8+r9+r10+r11+r12+10]      ; eight register addressing!

ok, I'm working and couldn't follow the last page well... Does this aberration actually works?
Title: Re: "Hello masm32", not a BOT, new member
Post by: nidud on April 28, 2017, 09:13:18 AM
deleted
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 28, 2017, 12:02:20 PM
Quote from: LordAdef on April 28, 2017, 09:01:13 AMDoes this aberration actually work?

Yes and no:  int 3
  lea rdx, [rcx+rdx+rsi+r8+r9+r10+r11+r12+10]      ; eight register addressing!


x64dbg:00000001400011E5 | CC                       | int3                               |
00000001400011E6 | 4B 8D 54 1C 0A           | lea rdx, qword ptr ds:[r12+r11+A]  |


So ML64 uses the last two registers r12, r11 for the encoding (hex A=dec 10). It "works" if these two registers contain meaningful values. But of course, a good assembler must throw an "invalid opcode" error. It's a fat Micros**t bug, nothing else.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 29, 2017, 03:45:30 PM
Guys, what do you think?

I´m tweaking the engine and like your opinion. I made some tests using a Double Buffer, instead of doing straight to HDC:

(all in WM_PAINT)
1. Main_Current: I´m printing everything to HDC
2. Main_MapDoubleBuffer: Using a Double Buffer where I only paint the bk map. The rest is still going straight to HDC (It´s the middle groung between the 2 others)
3. Main_All_in_DoubleBuffer: Everything is built in the Back Buffer.

All 3 options attached. Asm file compatible with ml, although my resources are not being joined (I don´t know why, pure ignorance of mine really)

There is a trade here:
-> Main_Current is faster, but flickers
-> All_in_DoubleBuffer is the fastest of the two using double buffer (curiously). Although I´m slower, the feel is more solid, since the image is less flickery.

Would you trade the speed of #1 for visual stability of #3? I inclined to do it.

My benchmarks:
QuoteEverything straight to HDC:
6458 us 6505 us 6544 us 6686 us 6454 us 6362 us 6433 us 6392 us 6306 us 6448 us 6390 us 6447 us 6544 us 6481 us 6899

ONly BK map is sent to Back Buffer, the rest is straight to HDC
7638 us 7766 us 7531 us 7544 us 7531 us 7581 us 7583 us 7596 us 7799 us 7729 us 7787 us 7711 us 7894 us 7698 us 7545

All to Back Buffer
7208 us 7151 us 7344 us 7215 us 7248 us 7112 us 7238 us 7384 us 7279 us 7258 us 7339 us 7165 us 7266 us 7265 us 7285

Cheers Alex
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 29, 2017, 06:17:23 PM
I've downloaded all three, and can't find any difference in speed. And all three flicker, not much but equally ::)
This is on Win7-64 and a Core i5 cpu.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 30, 2017, 01:10:30 AM
Quote from: jj2007 on April 29, 2017, 06:17:23 PM
I've downloaded all three, and can't find any difference in speed. And all three flicker, not much but equally ::)
This is on Win7-64 and a Core i5 cpu.

Any suggestion JJ?
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 30, 2017, 01:57:13 AM
   .IF uMsg==WM_CREATE
            invoke pIniFonts, hdc
            mCreateDC


Suggestion: Put all that stuff into the same file, it would be much easier to find it and understand what it does (select the word, hit F3).

More concretely: hdc is a local variable, i.e. it may contain anything. What are you passing to pIniFonts?
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 30, 2017, 02:11:47 AM
Quote from: jj2007 on April 30, 2017, 01:57:13 AM
   .IF uMsg==WM_CREATE
            invoke pIniFonts, hdc
            mCreateDC


Suggestion: Put all that stuff into the same file, it would be much easier to find it and understand what it does (select the word, hit F3).

More concretely: hdc is a local variable, i.e. it may contain anything. What are you passing to pIniFonts?

Ok, checking it out in 10 minutes.
Concerning the paint engine, do you think implementing a new test with the "scroll" Windows function would give me a better flickerless result? A quick test has shown me it may be the case, although the logic imposes some difficulties
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 30, 2017, 04:23:30 AM
ScrollWindow must use BitBlt internally, I doubt that it can be much faster.

I am too busy (and too tired) to look into the double buffering, Alex - but if it's done correctly, it should not flicker at all. For comparison, try sizing the Gdi+ example in File/New Masm source; the only item that flickers is the yellow box in the lower right...

Re pIniFonts:
004023A8        ³.  50                      push eax                               ; ÚhObject
004023A9        ³.  FF75 08                 push dword ptr [ebp+8]                 ; ³hDC => [Arg1]
004023AC        ³.  E8 E7010000             call <jmp.&gdi32.SelectObject>         ; ÀGDI32.SelectObject


Returns 0, invalid handle.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 30, 2017, 05:37:49 AM
I understand JJ, no worries.

Double buffering is not flickering for me. For scrolling, I even think it gets a worse result than compared to double buffering. the three exes in the zip.



Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 30, 2017, 05:52:34 AM
QuotepIniFonts proc hdc:DWORD
            ;----------------------------------------- MAP FONT -----------------------------------------------------------------------------------------------------------
            invoke CreateFont,12,0,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
                                           DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT, chr$("Courier New") ;ADDR FontName1 ;Lucida Console
            mov Font1, eax
            invoke SelectObject, hdc, eax
            mov OldFont, eax
           
            ;---------------------------------------- MAN FONT -----------------------------------------------------------------------------------------------------------
            invoke CreateFont,18,0,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
                                           DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,  chr$("Arial")
            mov Font2, eax
           
            ;---------------------------------------- LABEL FONT --------------------------------------------------------------------------------------------------------
            invoke CreateFont,52,0,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
                                           DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT, chr$("Arial Black")
            mov Font3, eax
           
            ;---------------------------------------- LABEL FONT 2 -----------------------------------------------------------------------------------------------------
            invoke CreateFont,28,0,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
                                           DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT, chr$("Arial")
            mov Font4, eax
           
            ;---------------------------------------- TEST FONT -----------------------------------------------------------------------------------------------------
            invoke CreateFont,12,0,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
                                           DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT, chr$("MapTst")
            mov Font5, eax

     ret
pIniFonts endp

I´m only using hdc to retrieve the default font, and restore it back when I´m done.
            invoke SelectObject, hdc, eax
            mov OldFont, eax

I made it as a proc but it was previously sitting in there.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 30, 2017, 06:33:54 AM
Quote from: LordAdef on April 30, 2017, 05:52:34 AM
I´m only using hdc to retrieve the default font, and restore it back when I´m done.
            invoke SelectObject, hdc, eax
            int 3
            mov OldFont, eax

If Olly (http://www.ollydbg.de/version2.html) is installed as \Masm32\OllyDbg\ollydbg.exe, hit F6 and have a look at eax and the error message.

Otherwise,
- activate MasmBasic.inc
- OxPT_Susy (disactivates the option, console will be default)
- fonts.asm, line 7:
            invoke SelectObject, hdc, eax
ifdef MbBufferGet
fdeb 4, "SelObj", eax, hdc, $Err$()
endif
            mov OldFont, eax
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on April 30, 2017, 10:17:59 AM
A quick help, please...


I need to iterate through an array of structures. [ebx*Bullet ] wont do it, but [2*Bullet] does. Pre compile thing? How do I do this?
   xor ecx, ecx
   @@:
   mov edi, offset man.bullets[ecx*Bullet].active
   .IF   dword Ptr [edi] == 1
      printf (" Bullet %d is active\n", dword Ptr [edi])
   .ENDIF
   inc ecx
   cmp ecx, 100
   jnz @B

QuoteBullet STRUCT
           active   dd      ?
               speed   dd     ?
               x      dd      ?
               y      dd      ?               
        Bullet ENDS

        Player STRUCT
           align 4
               x          dd ?
               y          dd ?
             sprite   dd   ?
               frmx   dd   ?
               frmy   dd   ?
               bullets   Bullet   100 dup (<>)  <==== These guys HERE
               kState   dd   ?   
        Player ENDS

QuoteIf Olly is installed as \Masm32\OllyDbg\ollydbg.exe, hit F6 and have a look at eax and the error message.
Thanks, I´ll have a look
Title: Re: "Hello masm32", not a BOT, new member
Post by: Siekmanski on April 30, 2017, 02:29:01 PM
Hi Alex,

Maybe ebx/ecx is trashed by the function "printf" ?

try this,

mov edi,offset Player.bullets
mov esi,0
find_active_bullets:
.if dword ptr[edi].Bullet.active == 1
    printf (" Bullet %d is active\n", esi)
.endif
add edi,sizeof Bullet
inc    esi
cmp    esi, 100
jne find_active_bullets


little hint: you can align the struct to 4 like this,
Player STRUCT 4
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on April 30, 2017, 05:19:58 PM
Quote from: LordAdef on April 30, 2017, 10:17:59 AM
A quick help, please...

I need to iterate through an array of structures. [ebx*Bullet ] wont do it, but [2*Bullet] does. Pre compile thing? How do I do this?
xor ecx, ecx
@@:
mov edi, offset man.bullets[ecx*Bullet].active
.IF dword Ptr [edi] == 1
printf (" Bullet %d is active\n", dword Ptr [edi])
.ENDIF
inc ecx
cmp ecx, 100
jnz @B


Marinus is right, ecx gets trashed - MB Print Str$() preserves ecx, but printf() doesn't. Simple solution:

.IF dword Ptr [edi] == 1
push ecx
printf (" Bullet %d is active\n", dword Ptr [edi])
pop ecx
.ENDIF


Btw no need for edi - this should work, too (not tested):
.IF man.bullets[ecx*Bullet].active == 1
push ecx
printf (" Bullet 1 is active\n")  ; 1 is it's value, for sure, so a constant will do ;-)
pop ecx
.ENDIF

Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on May 01, 2017, 08:07:39 AM
Thanks Marinus and JJ,

But ecx being trash is not the point. The point is my clause with a register is not building.

A test bed:
Quoteinclude \masm32\include\masm32rt.inc

        Bullet STRUCT
           active   dd      ?
          speed   dd        ?
          x      dd      ?
          y      dd      ?               
        Bullet ENDS

        Player STRUCT 4
               x          dd    ?
               y          dd    ?
              sprite   dd   ?
               frmx   dd   ?
               frmy   dd   ?
               bullets   Bullet   50 dup (<>)
               kState   dd   ?
        Player ENDS
       
.data
       man Player  <>
.code
start:
       mov   man.bullets[2*Bullet].active, TRUE
       mov    man.bullets[2*Bullet].speed, 100
       mov    man.bullets[2*Bullet].x, 100
       mov    man.bullets[2*Bullet].y, 100
       
       mov eax, 2
       ;mov   man.bullets[2*Bullet].active, FALSE      ; <== THIS WORKS
       mov   man.bullets[eax*Bullet].active, FALSE   ; <== THIS DOESN´T
        
       invoke ExitProcess, eax
end start

This is the problem:
Quote;mov   man.bullets[2*Bullet].active, FALSE      ; <== THIS WORKS
       mov   man.bullets[eax*Bullet].active, FALSE   ; <== THIS DOESN´T

Marinus, thanks for the align trick! Does this automatically align all items in the struct?
Title: Re: "Hello masm32", not a BOT, new member
Post by: Siekmanski on May 01, 2017, 08:41:55 AM
Quote from: LordAdef on May 01, 2017, 08:07:39 AM
Marinus, thanks for the align trick! Does this automatically align all items in the struct?
No, only the struct is aligned, but you can use align xx wihtin a struct or place a dummy byte.

this should work,

mov esi,offset man.bullets
mov ecx,sizeof Bullet

mov eax,2 ; the bullet number
mul ecx
mov dword ptr [esi+eax].Bullet.active,FALSE


edit:

Or in this case because the Bullet struct is 16 bytes,

mov   esi,offset man.bullets
mov   eax,2   ; the bullet number
shl   eax,4
mov   dword ptr [esi+eax].Bullet.active,FALSE
Title: Re: "Hello masm32", not a BOT, new member
Post by: HSE on May 01, 2017, 08:52:06 AM
Inside brackets you only can multiply by 2,4,8,...
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on May 01, 2017, 08:54:59 AM
Quote from: HSE on May 01, 2017, 08:52:06 AM
Inside brackets you only can multiply by 2,4,8,...


But this works fine:
mov   man.bullets[3*Bullet].active, TRUE         ; <== THIS WORKS

And eax in the test bed was == 2.



edit:
It works fine with a constant. Is this a pre-compiling thing?

Quote.const
   cINDEX      EQU   3 
...
         mov   man.bullets[cINDEX*Bullet].active, TRUE         ; <== THIS WORKS
Title: Re: "Hello masm32", not a BOT, new member
Post by: Siekmanski on May 01, 2017, 09:07:41 AM
Maybe because its an invalid scale value ?
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on May 01, 2017, 09:08:36 AM
Marinus,
QuoteNo, only the struct is aligned, but you can use align xx wihtin a struct or place a dummy byte.

this should work,

It sure works. However, I wished I could use that syntax, or at least understand why it´s not working

QuoteMaybe because its an invalid scale value ?

Sure, but in this case mov   man.bullets[3*Bullet].active, TRUE shouldn´t work either
Title: Re: "Hello masm32", not a BOT, new member
Post by: Siekmanski on May 01, 2017, 09:12:46 AM
does this work ?

mov   eax,2   ; the bullet number
shl   eax,4
mov man.bullets[eax].active, FALSE   

what assembler do you use ?
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on May 01, 2017, 09:32:07 AM
Quote from: LordAdef on May 01, 2017, 08:54:59 AM
It works fine with a constant. Is this a pre-compiling thing?

Exactly:
At compile time, any constant is fine.
At runtime, HSE's remark is correct: 2, 4 or 8 are the allowed scaling values.
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on May 01, 2017, 09:49:33 AM
Quote from: Siekmanski on May 01, 2017, 09:12:46 AM
does this work ?

mov   eax,2   ; the bullet number
shl   eax,4
mov man.bullets[eax].active, FALSE   

what assembler do you use ?

That works too.
I´m on HJWasm, since I usually use RichMasm. I try and keep compatibility using qEditor (ML)
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on May 01, 2017, 09:51:58 AM
QuoteAt compile time, any constant is fine.
At runtime, HSE's remark is correct: 2, 4 or 8 are the allowed scaling values.

I was suspecting that, and the constant test showed it. So, in that syntax the compiler can´t know the value of the register and thus generates an error. Got it.

Thanks everyone, this was instructive.
Title: Re: "Hello masm32", not a BOT, new member
Post by: jj2007 on May 01, 2017, 10:07:55 AM
Quote from: LordAdef on May 01, 2017, 09:49:33 AMI´m on HJWasm, since I usually use RichMasm. I try and keep compatibility using qEditor (ML)

This is how I test different assemblers:
; OPT_Assembler ML  ; somewhere in the file forces RichMasm to use \Masm32\bin\ml.exe (or any other exe...)

OPT is case-sensitive, the rest isn't.
Just put an x after the O: OxPT_anyoption to disable an option. If there are several options of the same type, the last one is valid:
...
end start
OPT_Arg1  fileA.txt
OPT_Arg1  fileB.txt

CL$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1011) will find fileB.txt
Title: Re: "Hello masm32", not a BOT, new member
Post by: LordAdef on May 01, 2017, 10:42:15 AM
NICE ONE!!!!! RM/MB always have a away around things..
Title: Re: "Hello masm32", not a BOT, new member
Post by: hutch-- on May 01, 2017, 02:20:38 PM
Something that some folks miss, a "syntax error" with an instruction means that the processor does not have a matching opcode for something in source code that has been fed to it. This applies to the multiplier range of 2, 4 and 8, each of which has a matching opcode, try it with any other number and you are trying to call a non existent opcode. The assembler "should" catch this but they can be a bit sloppy and miss a simple error like this, an error type the is mainly a typo.