The MASM Forum

General => The Workshop => Topic started by: felipe on May 13, 2017, 07:06:14 AM

Title: Crazy sounds
Post by: felipe on May 13, 2017, 07:06:14 AM
Well, this program remember me assembly programming in dos. But i don't understand why i can't use a loop for the function.  :eusa_snooty:


.386
.model  flat,stdcall
option  casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\kernel32.lib

.data
freqs   dword   440,900,1000,1500,390,2150,700,1000,903,1009   ; In hertz.
times   dword   1000,600,200,1020,190,500,720,1000,190,600     ; In milliseconds.

.code
begin   proc
        lea     ebx,freqs                                       
        lea     esi,times       
        push    [esi]
        push    [ebx]
        call    Beep
        inc     esi                                             ; Next dword...
        inc     esi
        inc     esi
        inc     esi
        inc     ebx
        inc     ebx
        inc     ebx
        inc     ebx
        push    [esi]
        push    [ebx]
        call    Beep
        inc     esi
        inc     esi
        inc     esi
        inc     esi
        inc     ebx
        inc     ebx
        inc     ebx
        inc     ebx
        push    [esi]
        push    [ebx]
        call    Beep
        inc     esi
        inc     esi
        inc     esi
        inc     esi
        inc     ebx
        inc     ebx
        inc     ebx
        inc     ebx
        push    [esi]
        push    [ebx]
        call    Beep
        inc     esi
        inc     esi
        inc     esi
        inc     esi
        inc     ebx
        inc     ebx
        inc     ebx
        inc     ebx
        push    [esi]
        push    [ebx]
        call    Beep
        inc     esi
        inc     esi
        inc     esi
        inc     esi
        inc     ebx
        inc     ebx
        inc     ebx
        inc     ebx
        push    [esi]
        push    [ebx]
        call    Beep
        inc     esi
        inc     esi
        inc     esi
        inc     esi
        inc     ebx
        inc     ebx
        inc     ebx
        inc     ebx
        push    [esi]
        push    [ebx]
        call    Beep
        inc     esi
        inc     esi
        inc     esi
        inc     esi
        inc     ebx
        inc     ebx
        inc     ebx
        inc     ebx
        push    [esi]
        push    [ebx]
        call    Beep
        inc     esi
        inc     esi
        inc     esi
        inc     esi
        inc     ebx
        inc     ebx
        inc     ebx
        inc     ebx
        push    [esi]
        push    [ebx]
        call    Beep
        inc     esi
        inc     esi
        inc     esi
        inc     esi
        inc     ebx
        inc     ebx
        inc     ebx
        inc     ebx
        push    [esi]
        push    [ebx]
        call    Beep
               
        push    0
        call    ExitProcess
begin   endp

        end     begin


But is really fun!  :biggrin:
Title: Re: Crazy sounds
Post by: LordAdef on May 13, 2017, 10:47:31 AM
any reason to not use "add esi, 5"?
Title: Re: Crazy sounds
Post by: felipe on May 13, 2017, 12:48:37 PM
Quote from: LordAdef on May 13, 2017, 10:47:31 AM
any reason to not use "add esi, 5"?

Well, at least before, inc was a shorter instruction, than was add...

Also, esi should be incremented by 4 not 5. This is because you have to address to increasing memory locations. Remember that each memory location in Intel's micro is a byte . And 4 bytes make a double word (dword).

The confusion may be in that the first memory address loaded to esi is like the "zero" position. So you increment esi by 4 and you obtain the next dword and so on.
Title: Re: Crazy sounds
Post by: jj2007 on May 13, 2017, 05:25:47 PM
inc is one byte
add esi, 127 is three bytes
add esi, 128 needs five bytes

In the unlikely case that...
- you need an add esi, 4
- esi points to a valid memory location
- you couldn't care less about eax
- and speed doesn't matter:
lodsd needs one byte 8)
Title: Re: Crazy sounds
Post by: TWell on May 13, 2017, 05:40:04 PM
Edited for poasm:.386
.model  flat,stdcall
option  casemap:none

includelib kernel32.lib
;extern ExitProcess:proc
;extern Beep:proc

.data
freqs   dword   440,900,1000,1500,390,2150,700,1000,903,1009   ; In hertz.
times   dword   1000,600,200,1020,190,500,720,1000,190,600     ; In milliseconds.

.code
WinMainCRTStartup   proc C
;        push    ebx
        lea     esi,freqs
        lea     edi,times
        mov     ebx, 10
@@:     push    dword ptr[edi]
        push    dword ptr[esi]
        call    Beep@8
        add     esi, 4
        add     edi, 4
        dec     ebx
        test    ebx,ebx
        jnz     @B
        push    0
        call    ExitProcess@4
WinMainCRTStartup   endp

        end     ;WinMainCRTStartup
Title: Re: Crazy sounds
Post by: LordAdef on May 13, 2017, 06:31:32 PM
QuoteAlso, esi should be incremented by 4 not 5.

Sorry, I didn´t count the incs correctly.

As TWell also suggested:

Quoteadd     esi, 4
        add     edi, 4

You should do fine with that and it´s clearer.
There´s a big debate about "inc eax" vs "add eax, 1" in terms of speed. But in your case I wouldn´t think twice and use add. That´s why I asked.
What if you needed to add 50?

One other thing to be checked, and I might be wrong: beep does not seem to work for every system anymore.
Title: Re: Crazy sounds
Post by: aw27 on May 13, 2017, 06:57:36 PM
Quote from: felipe on May 13, 2017, 07:06:14 AM
But is really fun!  :biggrin:

A bit noisy.
Listen to this:


.686
.XMM

    .MODEL FLAT, STDCALL
    option casemap:none
   
option dllimport:<kernel32.dll>
ExitProcess PROTO :DWORD
Beep PROTO  :DWORD,:DWORD   
Sleep PROTO  :DWORD
   
E1 EQU 329.63
F1 EQU 349.23
G1 EQU 392.0
A1 EQU 440.0
B1 EQU 493.88
C2 EQU 523.25
D2 EQU 587.33
E2 EQU 659.26

Q EQU 222.0
H EQU 444.0
W EQU 889.0
WZ EQU 1778.0   
                               
.data

FREQ  DD G1,G1,E1,F1,G1,A1,B1,C2,A1,B1,G1,F1
      DD G1,D2,E2,C2,D2,B1,C2,B1,A1,G1,F1,E1,G1
      DD C2,C2,C2,C2,B1,D2,D2,C2,B1,A1,A1,G1,B1,B1,B1,B1,A1,G1,G1,G1,A1,G1
      DD F1,E1


DURAC  DD H,WZ,Q,Q,H,H,Q,H,Q,H,H,WZ
       DD H,WZ,Q,Q,H,H,Q,H,Q,H,H,WZ,W
       DD Q,H,Q,H,Q,Q,H,Q,H,H,H,WZ,Q,H,Q,H,H,H,Q,H,H,Q
       DD Q,WZ

num_notes dd 48

NOTE_DUR dd 0.8

.code

playMusic proc uses ecx freq:real4, duration:real4
; play = duration*NOTE_DUR;
movss xmm0, duration
movss xmm1, xmm0 ; save
mulss xmm0, NOTE_DUR
cvtss2si eax, xmm0 ; convert to int

;off = duration - play;
subss xmm1, xmm0
cvtss2si ebx, xmm1 ; convert to int

movss xmm2, freq
cvtss2si edx, xmm2 ; convert to int
;Beep(freq, play);
INVOKE Beep, edx, eax
;Sleep(off);
INVOKE Sleep, ebx
ret
playMusic endp


start proc
mov ecx, num_notes
mov esi, offset FREQ
mov edi, offset DURAC
@loop:
INVOKE  playMusic, real4 ptr [esi], real4 ptr [edi]
add esi, TYPE FREQ
add edi, TYPE DURAC
loop @loop
invoke  ExitProcess, 0
start endp


end start
Title: Re: Crazy sounds
Post by: felipe on May 13, 2017, 09:44:22 PM
Quote from: aw27 on May 13, 2017, 06:57:36 PM
Quote from: felipe on May 13, 2017, 07:06:14 AM
But is really fun!  :biggrin:

A bit noisy.
Listen to this:


.686
.XMM

    .MODEL FLAT, STDCALL
    option casemap:none
   
option dllimport:<kernel32.dll>
ExitProcess PROTO :DWORD
Beep PROTO  :DWORD,:DWORD   
Sleep PROTO  :DWORD
   
E1 EQU 329.63
F1 EQU 349.23
G1 EQU 392.0
A1 EQU 440.0
B1 EQU 493.88
C2 EQU 523.25
D2 EQU 587.33
E2 EQU 659.26

Q EQU 222.0
H EQU 444.0
W EQU 889.0
WZ EQU 1778.0   
                               
.data

FREQ  DD G1,G1,E1,F1,G1,A1,B1,C2,A1,B1,G1,F1
      DD G1,D2,E2,C2,D2,B1,C2,B1,A1,G1,F1,E1,G1
      DD C2,C2,C2,C2,B1,D2,D2,C2,B1,A1,A1,G1,B1,B1,B1,B1,A1,G1,G1,G1,A1,G1
      DD F1,E1


DURAC  DD H,WZ,Q,Q,H,H,Q,H,Q,H,H,WZ
       DD H,WZ,Q,Q,H,H,Q,H,Q,H,H,WZ,W
       DD Q,H,Q,H,Q,Q,H,Q,H,H,H,WZ,Q,H,Q,H,H,H,Q,H,H,Q
       DD Q,WZ

num_notes dd 48

NOTE_DUR dd 0.8

.code

playMusic proc uses ecx freq:real4, duration:real4
; play = duration*NOTE_DUR;
movss xmm0, duration
movss xmm1, xmm0 ; save
mulss xmm0, NOTE_DUR
cvtss2si eax, xmm0 ; convert to int

;off = duration - play;
subss xmm1, xmm0
cvtss2si ebx, xmm1 ; convert to int

movss xmm2, freq
cvtss2si edx, xmm2 ; convert to int
;Beep(freq, play);
INVOKE Beep, edx, eax
;Sleep(off);
INVOKE Sleep, ebx
ret
playMusic endp


start proc
mov ecx, num_notes
mov esi, offset FREQ
mov edi, offset DURAC
@loop:
INVOKE  playMusic, real4 ptr [esi], real4 ptr [edi]
add esi, TYPE FREQ
add edi, TYPE DURAC
loop @loop
invoke  ExitProcess, 0
start endp


end start


error A2008: syntax error : dllimport
\test.asm(47) : error A2006: undefined symbol : xmm0
\test.asm(48) : error A2006: undefined symbol : xmm1
\test.asm(49) : error A2006: undefined symbol : xmm0
\test.asm(50) : error A2006: undefined symbol : xmm0
\test.asm(53) : error A2006: undefined symbol : xmm1
\test.asm(54) : error A2006: undefined symbol : xmm1
\test.asm(56) : error A2006: undefined symbol : xmm2
\test.asm(57) : error A2006: undefined symbol : xmm2
:(
Title: Re: Crazy sounds
Post by: felipe on May 13, 2017, 09:59:07 PM
Quote from: TWell on May 13, 2017, 05:40:04 PM
Edited for poasm:.386
.model  flat,stdcall
option  casemap:none

includelib kernel32.lib
;extern ExitProcess:proc
;extern Beep:proc

.data
freqs   dword   440,900,1000,1500,390,2150,700,1000,903,1009   ; In hertz.
times   dword   1000,600,200,1020,190,500,720,1000,190,600     ; In milliseconds.

.code
WinMainCRTStartup   proc C
;        push    ebx
        lea     esi,freqs
        lea     edi,times
        mov     ebx, 10
@@:     push    dword ptr[edi]
        push    dword ptr[esi]
        call    Beep@8
        add     esi, 4
        add     edi, 4
        dec     ebx
        test    ebx,ebx
        jnz     @B
        push    0
        call    ExitProcess@4
WinMainCRTStartup   endp

        end     ;WinMainCRTStartup


This worked fine in masm after removing @4 and @8. :t
Title: Re: Crazy sounds
Post by: aw27 on May 13, 2017, 10:09:25 PM
Quote from: felipe on May 13, 2017, 09:44:22 PM
error A2008: syntax error : dllimport
\test.asm(47) : error A2006: undefined symbol : xmm0
\test.asm(48) : error A2006: undefined symbol : xmm1
\test.asm(49) : error A2006: undefined symbol : xmm0
\test.asm(50) : error A2006: undefined symbol : xmm0
\test.asm(53) : error A2006: undefined symbol : xmm1
\test.asm(54) : error A2006: undefined symbol : xmm1
\test.asm(56) : error A2006: undefined symbol : xmm2
\test.asm(57) : error A2006: undefined symbol : xmm2
:(

For Masm, instead of
option dllimport:<kernel32.dll>
use
includelib kernel32.lib

If it does not compile, delete the Masm.exe or ML.exe you have, probably from last century, and look for a more recent Masm, they come free with Visual Studio Community Edition.

Title: Re: Crazy sounds
Post by: felipe on May 13, 2017, 10:16:38 PM
I already did this: "includelib kernel32.lib"

So this should be the problem:

"If it does not compile, delete the Masm.exe or ML.exe you have, probably from last century, and look for a more recent Masm, they come free with Visual Studio Community Edition. "

Thanks  :icon14:
Title: Re: Crazy sounds
Post by: felipe on May 13, 2017, 10:32:51 PM

.386
.model  flat,stdcall
option  casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\kernel32.lib

.data
freqs   dword   440,900,1000,1500,390,2150,700,1000,903,1009   ; In hertz.
times   dword   1000,600,200,1020,190,500,720,1000,190,600     ; In milliseconds.

.code
begin   proc
        mov     ebx,10
        lea     edi,freqs                                       
        lea     esi,times       

play_all:
        push    [esi]
        push    [edi]
        inc     esi
        inc     esi
        inc     esi
        inc     esi
        inc     edi
        inc     edi
        inc     edi
        inc     edi
        call    Beep
        dec     ebx
        test    ebx,ebx
        jnz     play_all
       
               
        push    0
        call    ExitProcess
begin   endp

        end     begin


Thanks Twell. :icon14: But, what's wrong with the other registers, such as ecx, why they give me troubles? For example: The same algo, but using ecx instead ebx and using the loop instruction. Assembly and link good, the program runs, but has a bad end.  :(
Title: Re: Crazy sounds
Post by: aw27 on May 13, 2017, 10:48:32 PM
Quote from: felipe on May 13, 2017, 10:32:51 PM
But, what's wrong with the other registers, such as ecx
eax, edx and ecx are volatile, i.e they will be used within the Beep call without preserving their state on entry. ebx is perserved. This is what the stdcall specification says!
If you understood my example you could see that I took all the care about that but knowing what the API calls would do. I knew that the API call would preserve the esi and edi registers, I knew they will not preserve the ecx registers so I saved it on entry to the playMusic routine and I knew they will preserve the ebx register so I was sure the value will not be changed by the Beep call and could use it in Sleep call.
Title: Re: Crazy sounds
Post by: felipe on May 13, 2017, 10:50:32 PM
"delete the Masm.exe or ML.exe you have, probably from last century, and look for a more recent Masm, they come free with Visual Studio Community Edition. "

I already have the vs community 2015. So i did a backup of ml and link, then i replaced this files with those of vs crap. Then i did have to add mspdb140.dll from vc in the bin directory of masm and after that worked fine.  :t

Good job, sounds like bossa nova i think.  :bgrin:
Title: Re: Crazy sounds
Post by: aw27 on May 13, 2017, 11:06:04 PM
Quote from: felipe on May 13, 2017, 10:50:32 PM
Then i did have to add mspdb140.dll from vc in the bin directory of masm and after that worked fine.  :t
It replaces the 19 years old crap you have there mspdb50.dll

Quote
Good job, sounds like bossa nova i think.  :bgrin:
La Paloma
Title: Re: Crazy sounds
Post by: jj2007 on May 14, 2017, 01:25:00 AM
Quote from: aw27 on May 13, 2017, 11:06:04 PMIt replaces the 19 years old crap you have there mspdb50.dll

And let's your code crash on older machines :bgrin:
Title: Re: Crazy sounds
Post by: aw27 on May 14, 2017, 01:37:37 AM
Quote from: jj2007 on May 14, 2017, 01:25:00 AM
Quote from: aw27 on May 13, 2017, 11:06:04 PMIt replaces the 19 years old crap you have there mspdb50.dll

And let's your code crash on older machines :bgrin:

True, no more waivers for bad code - let it crash everything.   :greenclp:
Title: Re: Crazy sounds
Post by: felipe on May 14, 2017, 03:45:59 AM
Quote from: aw27 on May 13, 2017, 10:48:32 PM
Quote from: felipe on May 13, 2017, 10:32:51 PM
But, what's wrong with the other registers, such as ecx
eax, edx and ecx are volatile, i.e they will be used within the Beep call without preserving their state on entry. ebx is perserved. This is what the stdcall specification says!

I didn't see this reply before. Thanks a lot.  :icon14:
I wasn't aware of this. I only knew that the parameters are passed (in this convention) in opposite order, that the function called cleans the stack and that the return value is in eax.
Thanks again,  :t. I have to keep learning.  :greenclp:
Title: Re: Crazy sounds
Post by: felipe on May 14, 2017, 04:05:24 AM
Quote from: aw27 on May 13, 2017, 10:48:32 PM
If you understood my example you could see that I took all the care about that but knowing what the API calls would do.

Now i know what the USES directive does.  :icon_mrgreen: