flat assembler
Message board for the users of flat assembler.

Index > Windows > Win32 example program help

Author
Thread Post new topic Reply to topic
computerex



Joined: 02 Dec 2007
Posts: 7
Location: Florida
computerex
Hi. I have just started learning assembly. I can code in c++, and I know a fair bit of win32 programming. I have been reading the FASM documentation, and the tutorial, but I learn better from looking at examples.

This code here I modified from the DIALOG example. The idea is that a user enters a number in the text field, and the dialog box adds a hard coded value to that number, 10, in this case, and spits it back to the user using a message box. Except this is spitting back eratic values. What is wrong?

Also, in the declaration of the "field" double word, what does the 10h stand for? I just saw it in an example. Embarassed

Code:
include 'win32ax.inc'

.data

field dw 10h

.code

  start:

        invoke  GetModuleHandle,0
        invoke  DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0
        or      eax,eax
        jz      exit
  exit:
        invoke  ExitProcess,0

.end start

proc DialogProc hwnddlg,msg,wparam,lparam
        push    ebx esi edi
        cmp     [msg],WM_COMMAND
        je      .wmcommand
        cmp     [msg],WM_CLOSE
        je      .wmclose
        xor     eax,eax
        jmp     .finish
  .wmcommand:
        cmp     [wparam],BN_CLICKED shl 16 + IDOK
        je      .display
        jmp     .processed

  .display:
        invoke  GetDlgItemText,[hwnddlg], 10, field, 10h
        add     [field],10
        invoke  MessageBox, HWND_DESKTOP, field, "caption", MB_OK
        jmp     .processed
  .wmclose:
        invoke  EndDialog,[hwnddlg],0
  .processed:
        mov     eax,1
  .finish:
        pop     edi esi ebx
        ret
endp

section '.rsrc' resource data readable

  directory RT_DIALOG,dialogs
  resource dialogs,\
           37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration

  dialog demonstration,'Add',70,70,190,175,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME
    dialogitem 'EDIT','',10,10,20,170,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP
    dialogitem 'BUTTON','OK',IDOK,85,150,45,15,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON
  enddialog
    
Post 02 Dec 2007, 22:25
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
problem is here
Code:
  invoke  MessageBox, HWND_DESKTOP, field, "caption", MB_OK     


second parameter of MessageBox is pointer to string. You pass number instead of pointer to string. You must first convert number to string, and only then you can use it.
Post 02 Dec 2007, 22:59
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
computerex



Joined: 02 Dec 2007
Posts: 7
Location: Florida
computerex
Any idea how to do that? I wish I had sprintf or itoa in assembly. Confused
Post 02 Dec 2007, 23:18
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
You do. Just link to "msvcrt.dll", and call those functions from there.

As an alternative, there is assembly library FASMLIB (written by me...) that provides this functionality too: fasmlib.x86asm.net
Post 03 Dec 2007, 00:18
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
handyman



Joined: 04 Jun 2007
Posts: 40
Location: USA - KS
handyman
use 'cinvoke wsprintf, ...'. Be sure to check out the formatting string definitions for the wsprinf. put formatting string in a data string and use pointer to it in command. In assembly all cinvoke, invoke, and stdcall commands use pointers to strings (if used) and not the actual strings for the call since these are macro commands that actually do parameter value pushes to the stack to pass data values/locations to the called process.
Post 03 Dec 2007, 00:27
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
isn't wsprintf for wide-char (UTF16) strings?
Post 03 Dec 2007, 00:52
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
No, but you can use wsprintfW if you want wide-char.
Post 03 Dec 2007, 01:21
View user's profile Send private message Reply with quote
computerex



Joined: 02 Dec 2007
Posts: 7
Location: Florida
computerex
Thanks for the replies. I tried wsprintf, and it gives even more eratic results. Entering a 3 gives 4198400. Maybe there is an overflow going on here?

Code:
.data

field  dw 10h
buff   rb 100
fmt    db '%i',0  

; snipping 
Within the dialog's message handling procedure:

.display:
        invoke  GetDlgItemText,[hwnddlg], 10, field, 10h
        add     [field],10
        cinvoke  wsprintf, buff, fmt, field
        invoke  MessageBox, HWND_DESKTOP, buff, "caption", MB_OK    

    
Post 03 Dec 2007, 01:34
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Oh yes, you have passed a pointer to the variable rather than the actual integer value, this is the correct call
Code:
cinvoke  wsprintf, buff, fmt, [field]    


Apart of null-terminated strings I can't remember another data type that must be passed as pointer to wsprintf.
Post 03 Dec 2007, 01:49
View user's profile Send private message Reply with quote
computerex



Joined: 02 Dec 2007
Posts: 7
Location: Florida
computerex
I read the msdn page on wsprintf, and at first did give the last argument as an object rather then a pointer, but that led to my message box looking like this:
Image

Can anyone just give me the corrected code? Wink
One this I really like about FASM is how easy and quick it is to start a project/build. In VC6 you have to mess with the thing for 15 minutes...
Post 03 Dec 2007, 01:59
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Quote:
In VC6 you have to mess with the thing for 15 minutes...

In VS6, eg. Visual Studio IDE. You can still fuck off the IDE, and use compiler directly, or with different IDE (Code::Blocks).
Post 03 Dec 2007, 02:09
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
computerex



Joined: 02 Dec 2007
Posts: 7
Location: Florida
computerex
vid wrote:
Quote:
In VC6 you have to mess with the thing for 15 minutes...

In VS6, eg. Visual Studio IDE. You can still fuck off the IDE, and use compiler directly, or with different IDE (Code::Blocks).


Yeah, but the IDE is nice. Intellisense is useful. The debugger isn't bad either.
Wink

Anyway, still stuck on that simple program...How the heck do I make it add two numbers and spit the result back onto the screen? I have new found respect for assembly programmers...I can't even make it add two numbers, even while using an advance assembler like FASM. Crying or Very sad
Post 03 Dec 2007, 03:59
View user's profile Send private message Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak
You need null termination. It's like throwing a '\0' and the end of a char array in C++. It's how the computer knows to stop printing the string.

Code:
invoke  MessageBox, HWND_DESKTOP, buff, "caption", MB_OK      


Should become:

Code:
invoke  MessageBox, HWND_DESKTOP, buff, <"caption",0>, MB_OK      


or

Code:
caption db "caption", 0 ;Note the null (0) termination (decleration of end). This belongs in the datat section, the second belongs in the code section.
invoke  MessageBox, HWND_DESKTOP, buff, caption, MB_OK     


For hex numbers, it's just a loop taking off 4 bits (1 hex digit) and converting it 0 to F then adding to it to reach a corrisponding value (look at charmap), which is pretty easy. You could declare a 9 byte array, making the last one a 0. Like below.

Quote:
Data section:
output db 9 dup(0) ;9 bytes (chars) all initialized with 0

CODE SECTION:
;This code is for converting, it goes before the printing. You don't seem to be using ebx, edx and ecx, so i'll use that instead of eax, but normally you'd use what you're not using for this.

mov ecx, 8
mov ebx, 0 ;gotta make sure it's clear.
mov bx, [field]
convertloop:
mov edx, ebx
and edx, 0xF ;4 bits from the right are kept to be worked with
add edx, 0x30
mov [output-1+ecx], dl ;DL is edx's furthest right byte, which needs to be the same size as what we're moving to.
shr ebx, 4 ;4 bits erased and to the next 4 bits next time around
loop convertloop
Post 03 Dec 2007, 06:22
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
No kohlrak, the string gets null-terminated automatically...

computerex, it is very funny what happened here, but have you realized that you requested the edit box's text and hence the number is already a string?

This would print your number (any content actually)
Code:
.display: 
        invoke  GetDlgItemText,[hwnddlg], 10, buff, 100  
        invoke  MessageBox, HWND_DESKTOP, buff, "caption", MB_OK    


Now, to do what you originally requested, wsprintf won't never help to convert the string to integer, and win32 API does not provide wsprinft counterpart (or it does?).

Well, here my code, I hope it works good
Code:
include 'win32ax.inc'

.data 

fmt    db '%d',0

field  dd ?
buff   rb 100

.code 

  start: 

        invoke  GetModuleHandle,0 
        invoke  DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0 
        or      eax,eax 
        jz      exit 
  exit: 
        invoke  ExitProcess,0 

.end start 

proc DialogProc hwnddlg,msg,wparam,lparam 
        push    ebx esi edi 
        cmp     [msg],WM_COMMAND 
        je      .wmcommand 
        cmp     [msg],WM_CLOSE 
        je      .wmclose 
        xor     eax,eax 
        jmp     .finish 
  .wmcommand: 
        cmp     [wparam],BN_CLICKED shl 16 + IDOK 
        je      .display 
        jmp     .processed 

  .display: 
        mov     esi, buff
        invoke  GetDlgItemText,[hwnddlg], 10, esi, 100

        xor     edx, edx
        xor     eax, eax
        jmp     .loadChar

        .strToIntLoop:
          sub     al, '0'
          cmp     al, 9
          ja      .invalidInput

          imul    edx, 10
          jc      .numberTooBig

          add     edx, eax

        .loadChar:
          lods    byte [esi]
          test    al, al
          jnz     .strToIntLoop

        add     edx, 10 ; Could overflow so if you don't want modular arithmetic then add post-check
        mov     [field], edx

        cinvoke wsprintf, buff, fmt, edx
        invoke  MessageBox, HWND_DESKTOP, buff, "caption", MB_OK
        jmp     .processed

        .invalidInput:
          invoke  MessageBox, HWND_DESKTOP, "Invalid input", "Error", MB_OK
          jmp     .processed

        .numberTooBig: ; Will be triggered on cases like 123456789123456789erhigufehi too...
          invoke  MessageBox, HWND_DESKTOP, "Number too big", "Error", MB_OK
          jmp     .processed

  .wmclose: 
        invoke  EndDialog,[hwnddlg],0 
  .processed: 
        mov     eax,1 
  .finish: 
        pop     edi esi ebx 
        ret 
endp 

section '.rsrc' resource data readable 

  directory RT_DIALOG,dialogs 
  resource dialogs,\ 
           37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration 

  dialog demonstration,'Add',70,70,190,175,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME 
    dialogitem 'EDIT','',10,10,20,170,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP
    dialogitem 'BUTTON','OK',IDOK,85,150,45,15,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON 
  enddialog     
Post 03 Dec 2007, 15:26
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Post 03 Dec 2007, 16:36
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
That would mean using CRT and the standard package does not provide any headers for it. But, what is the problem on using wsprintf anyway? Perhaps do you mean sscanf to avoid converting the number yourself? The problem of lacking of proper headers still exist with this one. Such headers will be available on the community package for sure, though Wink
Post 03 Dec 2007, 17:19
View user's profile Send private message Reply with quote
handyman



Joined: 04 Jun 2007
Posts: 40
Location: USA - KS
handyman
computerex,

Another way to get integer numbers to the screen is to use 'SetDlgItemInt'

I use this in the prime number program source that I posted at

http://board.flatassembler.net/topic.php?t=7153

Please use the code at the bottom of the post list, not the first one.
Smile
Post 04 Dec 2007, 00:49
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
hoho, how simple Very Happy And of course also exists GetDlgItemInt so there is no need for conversion loop anymore.

I leave the links for reference:
GetDlgItemInt
SetDlgItemInt
Post 04 Dec 2007, 01:09
View user's profile Send private message Reply with quote
computerex



Joined: 02 Dec 2007
Posts: 7
Location: Florida
computerex
Excellent! Thanks for the help guys, finally got a working version! Unfortunately it only works for integers. Entering a real number causes GetDlgInt to fail. Next step is to find out how to use sprintf in FASM!

Final:

Code:
include 'win32ax.inc'

.data

succes db ?
buff   dd ?
fmt    db '%d',0
.code

  start:

        invoke  GetModuleHandle,0
        invoke  DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0
        or      eax,eax
        jz      exit
  exit:
        invoke  ExitProcess,0

.end start

proc DialogProc hwnddlg,msg,wparam,lparam
        push    ebx esi edi
        cmp     [msg],WM_COMMAND
        je      .wmcommand
        cmp     [msg],WM_CLOSE
        je      .wmclose
        xor     eax,eax
        jmp     .finish
  .wmcommand:
        cmp     [wparam],BN_CLICKED shl 16 + IDOK
        je      .display
        jmp     .processed

  .display:
        invoke  GetDlgItemInt,[hwnddlg], 10, succes, TRUE
        cmp     [succes], TRUE
        jne     .error
        mov     edx,eax
        add     edx,10
        invoke  wsprintf, buff, fmt, edx
        invoke  MessageBox, HWND_DESKTOP, buff, "caption", MB_OK
        jmp     .processed
  .error:
        invoke  MessageBox, HWND_DESKTOP, "You have entered a real number", "Error!", MB_OK+MB_ICONEXCLAMATION
        jmp     .processed
  .wmclose:
        invoke  EndDialog,[hwnddlg],0
  .processed:
        mov     eax,1
  .finish:
        pop     edi esi ebx
        ret
endp

section '.rsrc' resource data readable

  directory RT_DIALOG,dialogs
  resource dialogs,\
           37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration

  dialog demonstration,'Add',70,70,190,175,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME
    dialogitem 'EDIT','',10,10,20,170,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP
    dialogitem 'BUTTON','OK',IDOK,85,150,45,15,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON
  enddialog
    
Post 05 Dec 2007, 03:45
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. Also on YouTube, Twitter.

Website powered by rwasa.