Hi MASM masters,
I'm trying to figure out how to change this routine in order to display
the formatted number of cycles a routine takes.
The part to modify is the first part of the second line of text displayed by
MsgBox:
.686 ; create 32 bit code
; for later processors
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include c:\masm32\include\windows.inc ; always first
; -----------------------------------------------------------------
; include files that have MASM format prototypes for function calls
; -----------------------------------------------------------------
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc
; ------------------------------------------------
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ------------------------------------------------
includelib c:\masm32\lib\gdi32.lib
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
;--------------------------------------------------------------------
mb_ok equ 0 ;mb_ok gets the value "0"
hWnd equ 0 ;handler for the object
lpText equ offset text ;set a pointer to the text
lpCaption equ offset caption ;set a pointer to the caption
; here we have our Data
.Data
text db "Hey Dude! your routine has taken some",13,10 ; first row of the text(with word-wrap)
db "xxx,xxx,xxx,xxx,xxx CPU cycles! Are you satisfied?",0
; second row, terminated with "0"
caption db "ASM Performance Test",0 ;Captionstring, 0-terminated
; and here we start with our code
.Code
Main:
; let's display the results :))
push mb_ok ;PUSH value for uType
push lpCaption ;PUSH Pointer to Caption
push lpText ;PUSH Pointer to Text
push hWnd ;PUSH Masterhandle
call MessageBoxA ;CALL MessageBoxA
CALL ExitProcess ;End (exit) program
End Main ;End of code
;-----------------------------------END--------------------------------
How can I manage this part of the string:
db "xxx,xxx,xxx,xxx,xxx CPU cycles! Are you satisfied?",0
; second row, terminated with "0"
to replace "xxx,xxx,xxx,xxx,xxx" with the formatted number string obtained elsewhere?
Thanks
Frank
A quick example for you to give an idea :
include GetCompName.inc
NAME_BUFF_SIZE = MAX_COMPUTERNAME_LENGTH + 1
.data
nSize dd NAME_BUFF_SIZE
format1 db 'The computer name = %s',0
capt db 'Hello',0
.data?
NameBuffer db NAME_BUFF_SIZE dup(?)
buffer2 db 100 dup(?)
.code
start:
invoke GetComputerName,ADDR NameBuffer,ADDR nSize
invoke wsprintf,ADDR buffer2,ADDR format1,ADDR NameBuffer
invoke MessageBox,0,ADDR buffer2,ADDR capt,MB_OK
invoke ExitProcess,0
END start
Quote from: Vortex on May 15, 2010, 10:01:23 AM
A quick example for you to give an idea :
include GetCompName.inc
NAME_BUFF_SIZE = MAX_COMPUTERNAME_LENGTH + 1
.data
nSize dd NAME_BUFF_SIZE
format1 db 'The computer name = %s',0
capt db 'Hello',0
.data?
NameBuffer db NAME_BUFF_SIZE dup(?)
buffer2 db 100 dup(?)
.code
start:
invoke GetComputerName,ADDR NameBuffer,ADDR nSize
invoke wsprintf,ADDR buffer2,ADDR format1,ADDR NameBuffer
invoke MessageBox,0,ADDR buffer2,ADDR capt,MB_OK
invoke ExitProcess,0
END start
OK. Thanks, Vortex.
In order to learn something I have to dissect any single line and try to
understand its meaning.
so:
include GetCompName.inc
are the usual Includes. No problem. :P
NAME_BUFF_SIZE = MAX_COMPUTERNAME_LENGTH + 1
this should be a MASM directive or EQUATE to make one variable name
means something else. Isn't it? ::)
.data
nSize dd NAME_BUFF_SIZE
format1 db 'The computer name = %s',0
capt db 'Hello',0
Here we have some variable declarations and initializations before CALLing
Windows APIs. Is it true?
::)
.data?
NameBuffer db NAME_BUFF_SIZE dup(?)
buffer2 db 100 dup(?)
here you use a different method than the one I was trying to implement,
you use uninitialized variables, while I was thinking about replacing bytes
in an initialized variable.
start:
invoke GetComputerName,ADDR NameBuffer,ADDR nSize
You are CALLing an API to get the Computer Name, passing it 2 ADDRESSES
for the buffer and the size [MAX_COMPUTERNAME_LENGTH + 1].
invoke wsprintf,ADDR buffer2,ADDR format1,ADDR NameBuffer
This one is another API CALL but I actually don't know what it does, :(
or why we have to use it before CALLing MsgBox.
invoke MessageBox,0,ADDR buffer2,ADDR capt,MB_OK
invoke ExitProcess,0
eventually you CALL the MsgBox with the strings to display and
exit after that.
Would you correct and explain the points I didn't get?
Thanks
Frank
The buffer to receive the computer name should have a size of MAX_COMPUTERNAME_LENGTH + 1 characters :
http://msdn.microsoft.com/en-us/library/ms724295%28VS.85%29.aspx
NAME_BUFF_SIZE = MAX_COMPUTERNAME_LENGTH + 1
MAX_COMPUTERNAME_LENGTH is expanded to the actual value 15 and NAME_BUFF_SIZE becomes 15 + 1 = 16
Quote
Here we have some variable declarations and initializations before CALLing
Windows APIs. Is it true?
Yes, that's true.
.data?
NameBuffer db NAME_BUFF_SIZE dup(?)
buffer2 db 100 dup(?)
They are uninitialized variables to receive the computer name and the formatted string created by wsprintf.
invoke wsprintf,ADDR buffer2,ADDR format1,ADDR NameBuffer
Quote
The wsprintf function formats and stores a series of characters and values in a buffer. Any arguments are converted and copied to the output buffer according to the corresponding format specification in the format string. The function appends a terminating null character to the characters it writes, but the return value does not include the terminating null character in its character count.
format1 db 'The computer name = %s',0
wsprintf replaces %s with the computer name.
Thanks Vortex, everything should be clear now. :U
As I was working on the replacement task of the text to be displayed inside the
MsgBox, I eventually came up with this first sample:
;--------------------------------------------------------------------
; MsgBox displaying messages about routine performance
;--------------------------------------------------------------------
.686 ; create 32 bit code
; for later processors
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include c:\masm32\include\windows.inc ; always first
; -----------------------------------------------------------------
; include files that have MASM format prototypes for function calls
; -----------------------------------------------------------------
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc
; ------------------------------------------------
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ------------------------------------------------
includelib c:\masm32\lib\gdi32.lib
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
;--------------------------------------------------------------------
mb_ok equ 0 ;mb_ok gets the value "0"
hWnd equ 0 ;handler for the window
lpText equ offset text ;set a pointer to the text
lpCaption equ offset caption ;set a pointer to the caption
; here we have our Data
.Data
text db "Hey Dude! your routine has taken some",13,10 ; first row of the text(with word-wrap)
db "xxx,xxx,xxx,xxx,xxx CPU cycles! Are you satisfied?",0
; second row, terminated with "0"
fnum db "371,568,905,207,572 " ; formatted number to display
dist_txt dd 39 ; distance from the beginning of "text" string to replace
len_txt dd 20 ; lenght [number] of bytes to replace
caption db "ASM Performance Test",0 ;Captionstring, 0-terminated
; and here we start with our code
.Code
Main:
; lets display the results :))
time_to_replace:
mov edx,offset text ; address of text
add edx,39 ; starting point to replace into "text" string
mov esi,offset fnum ; address of "fnum" with the formatted number
mov ecx,20 ; number of bytes to replace
replacing_task:
mov eax,[esi] ; getting 4 bytes from the formatted string number
mov [edx],eax ; moving them to the text to be displayed
add esi,4 ; moving 4 bytes forward
add edx,4 ; into both source and target string
sub ecx,4 ; managing the counter loop to see if I moved them all
jnz replacing_task ; if not all of them moved do it again
display_box:
push mb_ok ;PUSH value for uType
push lpCaption ;PUSH Pointer to Caption
push lpText ;PUSH Pointer to Text
push hWnd ;PUSH Masterhandle
call MessageBox ;CALL MessageBox
CALL ExitProcess ;End (exit) program
End Main ;End of code
;-----------------------------------END--------------------------------
Strangely enough it seems to work. :lol
But it is very limited, as it only replaces and displays a 20 bytes formatted number string.
This limit is due to the fact I'm using the .data with fixed lenght variables
already initialized. I have to use uninitialized variables in the .data? section
in order to have a more generalized routine with variable lenght of data to display.
Working on it with all the samples you guys have provided. :P
Frank
You coud always go with using format strings (even ones you just concatenate with your results to make larger strings) and allocated memory, that way your string length limits are only those imposed by memory and Windows itself. This idea seems clunky though and inefficient.
HR,
Ghandi