flat assembler
Message board for the users of flat assembler.

Index > Windows > Relapse

Author
Thread Post new topic Reply to topic
keantoken



Joined: 19 Mar 2008
Posts: 69
keantoken
Hello all.

I came here a long time ago wanting to learn assembly. I gave up for the moment to pursue other things, after writing a bunch of nearly useless code for a dubious experiment.

Since then I've moved on to Linux (ubuntu Lucid). Due to the lack of assembly info for linux GUI's, I'm content to run the windows version of FASM in WINE and use the WINE interface, which is the quickest method to get SOMETHING done.

Since I've never learned a language before, I'd like to ask for your patience while I ask some simple questions.

Right now I'm trying to whip up some instant gratification to make this venture seem worth my time.

I'm using the TEMPLATE.asm file in the examples directory, and want to add some of my own code to it to make it do my bidding. I've attached it in code at the bottom for quick reference.

What I want to know is where I should start writing my code. I think It should be either above or below msg_loop, but the MSDN is really vague on what the Message syscalls do, so I can't figure out what this section is for. My best guess is that it tells me if the exit button has been pressed, right? Because if the return value is above one, it exits. So I think my code should go before, right?

Code:
; Template for program using standard Win32 headers

format PE GUI 4.0
entry start

include 'win32w.inc'

section '.data' data readable writeable

  _class TCHAR 'FASMWIN32',0
  _title TCHAR 'yeahyeahyeah',0
  _error TCHAR 'Startup failed.',0

  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class

  msg MSG

section '.text' code readable executable

  start:

        invoke  GetModuleHandle,0
        mov     [wc.hInstance],eax
        invoke  LoadIcon,0,IDI_APPLICATION
        mov     [wc.hIcon],eax
        invoke  LoadCursor,0,IDC_ARROW
        mov     [wc.hCursor],eax
        invoke  RegisterClass,wc
        test    eax,eax
        jz      error

        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,800,192,NULL,NULL,[wc.hInstance],NULL
        test    eax,eax
        jz      error

  msg_loop:
        invoke  GetMessage,msg,NULL,0,0
        cmp     eax,1
        jb      end_loop
        jne     msg_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     msg_loop

  error:
        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

  end_loop:
        invoke  ExitProcess,[msg.wParam]

proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam
        cmp     [wmsg],WM_DESTROY
        je      .wmdestroy
  .defwndproc:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp     .finish
  .wmdestroy:
        invoke  PostQuitMessage,0
        xor     eax,eax
  .finish:
        ret
endp

section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL'

  include 'api\kernel32.inc'
  include 'api\user32.inc'
    


Thanks,
- keantoken
Post 27 Nov 2010, 07:18
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17248
Location: In your JS exploiting you and your system
revolution
Your code goes in WindowProc.

The message loop will dispatch relevant messages to your WindowProc procedure. Inside WindowProc you check wmsg to what you need to do.
Post 27 Nov 2010, 07:56
View user's profile Send private message Visit poster's website Reply with quote
keantoken



Joined: 19 Mar 2008
Posts: 69
keantoken
Okay, the "uses" operator in the WindowProc statement determine which registers are used to call the function. does this mean I can write the statement differently and cause it to use different registers?

Thanks,
- keantoken
Post 27 Nov 2010, 08:23
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17248
Location: In your JS exploiting you and your system
revolution
See the MINIPAD example for a slightly more thorough use of WindowProc. And when you really feel confident see the FASMW source for a full program usage example.

The "uses" is only there to save and restore clobbered registers, you can't change it unless your code doesn't use a particular register.
Post 27 Nov 2010, 08:34
View user's profile Send private message Visit poster's website Reply with quote
keantoken



Joined: 19 Mar 2008
Posts: 69
keantoken
Oh, so it pushes them to the stack or some place out of sight so you don't risk sending garbage to windows?

I succeeded in creating a messagebox, but I broke the program too.

1: If I want to receive user input from the messagebox, do I need to give it a specific handle?
2: Where does the input from the MessageBox go? Is it put in [wmsg] or something like that? Google is stubborn.

- keantoken
Post 27 Nov 2010, 10:48
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17248
Location: In your JS exploiting you and your system
revolution
keantoken wrote:
Oh, so it pushes them to the stack or some place out of sight so you don't risk sending garbage to windows?
Kind of. You push them on the stack so that later you can restore them when you return to the caller.
keantoken wrote:
I succeeded in creating a messagebox, but I broke the program too.

1: If I want to receive user input from the messagebox, do I need to give it a specific handle?
2: Where does the input from the MessageBox go? Is it put in [wmsg] or something like that? Google is stubborn.
MessageBox is very limited. It can only return a value that indicates which button was pressed by the user to close it.

Instead of searching for wmsg (which is your internal variable name only) try searching for MessageBox to get the MS documentation page.
Post 27 Nov 2010, 10:53
View user's profile Send private message Visit poster's website Reply with quote
keantoken



Joined: 19 Mar 2008
Posts: 69
keantoken
I've been looking at this page all along, but it doesn't tell me where the return value ends up.

http://msdn.microsoft.com/en-us/library/ms645505%28VS.85%29.aspx

- keantoken
Post 27 Nov 2010, 11:24
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17248
Location: In your JS exploiting you and your system
revolution
The stdcall calling convention uses EAX for return value.
Post 27 Nov 2010, 11:30
View user's profile Send private message Visit poster's website Reply with quote
keantoken



Joined: 19 Mar 2008
Posts: 69
keantoken
Okay, but I put

Code:
cmp eax,1
je  end_loop    


in a variety of places and clicking the OK button still doesn't exit. Instead the program just loops and creates another messagebox, and it's impossible to use the exit button to close the program.

- keantoken
Post 27 Nov 2010, 11:55
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17248
Location: In your JS exploiting you and your system
revolution
Show your code.
Post 27 Nov 2010, 11:59
View user's profile Send private message Visit poster's website Reply with quote
keantoken



Joined: 19 Mar 2008
Posts: 69
keantoken
Nevermind, I figured out what I did wrong. Something really stupid.

Well, I've gotten a few lines of text further during this latter half of my day, tomorrow I want to do some kind of calculation and display it in the text box.

Lol, I wrote a square root algorithm in assembly once. I'll have to look at it again to see if it's any good...

To bed and thanks,
- keantoken
Post 27 Nov 2010, 12:08
View user's profile Send private message Reply with quote
keantoken



Joined: 19 Mar 2008
Posts: 69
keantoken
Okay, I want the messagebox to show up 4 seconds after the program start. What do I use to delay for 4 seconds?

I used SignalObjectAndWait,NULL,NULL,4000,FALSE but it doesn't appear to work past a few hundred mS. Or maybe I'm using it wrong.

I think my first project will be to make a template for testing calculator algorithms and displaying finish times, and see how fast I can make them. Then I might make fast math macros or includes or whatever you do with those.

So what do people usually do to measure the speed of code?

- keantoken
Post 28 Nov 2010, 01:25
View user's profile Send private message Reply with quote
keantoken



Joined: 19 Mar 2008
Posts: 69
keantoken
I found this:

http://msdn.microsoft.com/en-us/library/ms644905%28v=VS.85%29.aspx

http://cplus.about.com/od/howtodothingsi2/a/timing.htm

How do get the compiler to put the lpFrequency data somewhere where I can use it? I notice the GetMessage function uses msg, which is also in the data section, but using the same syntax to create a lpFrequency variable gives me a compiler error.

- keantoken
Post 28 Nov 2010, 01:39
View user's profile Send private message Reply with quote
drobole



Joined: 03 Nov 2010
Posts: 67
Location: Norway
drobole
To sleep for 4 seconds you can use the Sleep function from Windows API.
To do high resolution measuring you could try the QueryPerformanceCounter function.
I don't have any assembly example of those but I know they are often used in C++. You should be able to find C++ examples of those functions online, and since the difference between assembly and C/C++ is all but cosmetic you should be able to apply them to fasm pretty easily.

If you prefer to work with linux, like me, I don't think you should go through the wine libraries. Go native with either Xlib or XCB.

Another option is to link your assembly to the fltk library, making your application cross platform friendly.

If you need a debugger for linux you could look into fdbg or edb, which is GUI based.

Just my opinion
Post 28 Nov 2010, 21:34
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 2900
Location: [RSP+8*5]
bitRAKE
keantoken wrote:
So what do people usually do to measure the speed of code?
RDTSC instruction for small scale timing. Still useful despite caveats. Need to know clock rate to convert time to seconds, but not important in comparative analysis (i.e. this code is 15% faster than my previous attempt; or code is performing logarithmic / linear / quadratic / etc.).

http://www.strchr.com/performance_measurements_with_rdtsc (...and comments.)

Quote:
Constant TSC behavior ensures that the duration of each clock tick is uniform and supports the use of the TSC as a wall clock timer even if the processor core changes frequency. This is the architectural behavior moving forward for all Intel processors.

_________________
¯\(°_o)/¯ unlicense.org
Post 28 Nov 2010, 22:51
View user's profile Send private message Visit poster's website Reply with quote
keantoken



Joined: 19 Mar 2008
Posts: 69
keantoken
Thanks everyone.

Haven't been at this for a few days, but...

I still can't figure out how you create variables. I need to create a rewritable variable to store edx:eax in after the RDTSC function. I want to try:

Code:
        xor     eax,eax
        invoke  CPUID
        invoke  RDTSC
        mov     [clcks],edx:eax    


But, do I need to state clcks as a variable beforehand?

- keantoken
Post 04 Dec 2010, 19:19
View user's profile Send private message Reply with quote
keantoken



Joined: 19 Mar 2008
Posts: 69
keantoken
Okay, that didn't work.

BUT I figured out that putting

Code:
clcks         dd   ?    


At the start didn't cause an error. So I've reverted to the QueryPerformanceCounter temporarily just to get something done.

So far it compiles without error, which is a good sign. By chance does anyone know how to convert the counter return value to unicode so I can display it in the messagebox?

And yes, I think I know how ridiculous this must look. It was also gruesome while I was (and still am) learning analog electronics at DIYAudio.com. However I am now a respected member of the community.

- keantoken
Post 04 Dec 2010, 21:05
View user's profile Send private message Reply with quote
keantoken



Joined: 19 Mar 2008
Posts: 69
keantoken
Here is the program currently.

Code:
; Template for program using standard Win32 headers

format PE GUI 4.0
entry start

include 'win32w.inc'

section '.data' data readable writeable

  _class TCHAR 'FASMWIN32',0
  _title TCHAR 'yeahyeahyeah',0
  _error TCHAR 'Startup failed.',0
  _die   TCHAR 'DIED!',0
  _bye   TCHAR 'bye',0

  clcks         dd   ?

  wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class

  msg MSG

section '.text' code readable executable

  start:

        invoke  GetModuleHandle,0
        mov     [wc.hInstance],eax
        invoke  LoadIcon,0,IDI_APPLICATION
        mov     [wc.hIcon],eax
        invoke  LoadCursor,0,IDC_ARROW
        mov     [wc.hCursor],eax
        invoke  RegisterClass,wc
        test    eax,eax
        jz      error

        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,800,192,NULL,NULL,[wc.hInstance],NULL
        test    eax,eax
        jz      error

  msg_loop:
        invoke  GetMessage,msg,NULL,0,0
        cmp     eax,1
        jb      end_loop
        jne     msg_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     msg_loop

  error:
        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

  end_loop:
        invoke  ExitProcess,[msg.wParam]

proc WindowProc uses eax ebx esi edi, hwnd,wmsg,wparam,lparam
        cmp     [wmsg],WM_DESTROY
        je      .wmdestroy
        xor     eax,eax
        invoke  QueryPerformanceFrequency,[clcks]
        invoke  MessageBox,NULL,[clcks],_die,MB_OK+MB_ICONEXCLAMATION+MB_SYSTEMMODAL
        cmp     eax,1
        je      end_loop
  .defwndproc:
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp     .finish
  .wmdestroy:
        invoke  PostQuitMessage,0
        xor     eax,eax
  .finish:
        ret
endp

section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL'

  include 'api\kernel32.inc'
  include 'api\user32.inc'
                                                                                                             


With this I tried to get the counter frequency in clcks and then used it in the messagebox call so that even if not the actual number, I could perhaps get a random ASCII character to show up. No such luck. It just reverts to one of the inbuilt icons or "ERROR".

Hmmm.

- keantoken
Post 04 Dec 2010, 21:28
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.