I'm trying to show the current time in my little proggy, so after finding a few examples to refer to, in this case "GetTime.asm", I added the following line to my code, which appears to be the source of my program crashing all of the time.
mov str1, cat$(str1,hour,":",minute,":",second)
(Included is my entire project as it stands now. Note: I had to include the entire path to the macros as I have yet to figure out how to point to them during assembly... I'm using RadASM 3.x as my IDE. Any help on this would also be greatly appreciated.)
As near as I can tell, calling szMultiCat is the culprit, but I'm not sure why. OllyDbg reports
Quote"Access Violation when reading [00000000]"
Can someone steer me in the right direction on this one?
Spare us the " (Solved) " title, this forum is not a paid help desk.
szmulticat WILL always bomb out on you if you don't tell it the correct number of items you are pushing on the stack... can't look at code i am out rescuing people with my snowblower
DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL str1:DWORD
LOCAL hour:DWORD
LOCAL minute:DWORD
LOCAL second:DWORD
invoke GetLocalTime,ADDR LocalTime
movzx eax, LocalTime.wHour
mov hour, ustr$(eax)
movzx eax, LocalTime.wMinute
mov minute, ustr$(eax)
movzx eax, LocalTime.wSecond
mov str1, cat$(str1,hour,":",minute,":",second)
when you call cat$, str1 is some undefined value (maybe 0)
try this
mov str1, cat$(hour,":",minute,":",second)
not sure if it's right - i don't use cat$ :P
it is also a good idea to read the documentation:
QuoteIf the source buffer does not already have string data in it, the first byte MUST be set to a zero byte so it is seen as a zero length string.
Quote from: dedndave on December 28, 2010, 07:04:14 PM
not sure if it's right - i don't use cat$ :P
Dave,
What is your method for doing something like this?
(BTW, I erased that 'str1' and tried that; still crashes.)
Gunner,
I'm not calling szmulticat directly... cat$ (from macros.asm) uses it like this:
txt equ <invoke szMultiCat,>
I have no idea how it works either (this is a new way to code to me).
qWord,
Where did you find that quote?
-Shooter
Quote from: Shooter on December 28, 2010, 07:16:38 PMWhere did you find that quote?
look at \masm32\help\hlhelp.chm
qWord
Quote from: qWord on December 28, 2010, 07:20:43 PM
look at \masm32\help\hlhelp.chm
#1) It sure would've been nice for me to have known that before,
#2) I changed my code to this, but it still crashes:
TimeStr DD 16 Dup (0)
mov TimeStr, cat$(TimeStr,hour,":",minute,":",second)
Your first para needs to be a ptr to a buffer that is big enough to hold the string.
szMulticat:
1. pcount is the number of zero terminated strings to append.
2. lpBuffer is the address of the buffer to appends the strings to.
3. args is the comma seperated parameter list.
Quote from: jj2007 on December 28, 2010, 07:40:29 PM
Your first para needs to be a ptr to a buffer that is big enough to hold the string.
szMulticat:
1. pcount is the number of zero terminated strings to append.
2. lpBuffer is the address of the buffer to appends the strings to.
3. args is the comma seperated parameter list.
As I am making a call to a macro that makes another call to another macro that invokes szmulticat, I have no idea how to set those parameters. I used this bit of code like it was written in GetTime.asm (except I deleted a few strings), an example file in the MASM32 directory.
The point being: I'm just trying to add the current time to my dialog so I can tell if the clock set up to local time or UTC. This was the only approach I found using "SYSTEMTIME" that had a dialog to display in, albeit MESSAGBOX, but still a dialog.
-Shooter
INVOKE SendDlgItemMessage,hWin,103,WM_SETTEXT, 0, OFFSET lpbData+NULL
INVOKE SendDlgItemMessage,hWin,105,WM_SETTEXT, 0, DWORD PTR [lpbIP]+NULL
INVOKE SendDlgItemMessage,hWin,107,WM_SETTEXT, 0, DWORD PTR [str1]+NULL
ok - NULL is an EQUate
someplace in windows.inc, you'll find something like
NULL EQU 0
so, "OFFSET lpbData+NULL" is the address of lpbData, plus 0
"DWORD PTR [lpbIP]+NULL" is the dword value at address lpbIP
"DWORD PTR [str1]+NULL" is the dword value at address str1
you can't tack a null string terminator onto the end of data that way
these make more sense...
INVOKE SendDlgItemMessage,hWin,103,WM_SETTEXT, 0, lpbData
INVOKE SendDlgItemMessage,hWin,105,WM_SETTEXT, 0,lpbIP
INVOKE SendDlgItemMessage,hWin,107,WM_SETTEXT, 0, str1
although, i didn't disect the code to see
you are using GoAsm i think - i don't have it installed
i think this line could go away altogether
mov str1, cat$(str1,hour,":",minute,":",second)
as well as the str1 variable
INVOKE SendDlgItemMessage,hWin,107,WM_SETTEXT, 0,Cat$(hour,":",minute,":",second)
looks like it might work :bg
if i want to concatonate strings, i usually write my own code to do it
that is because i haven't played with all the macros, yet
and because i have done it that way for 25 years :P
that doesn't mean that my way is the right way
Dave,
I'm using masm32.
Also, if I comment out the line that contains "cat$", the program works, even with these lines:
INVOKE SendDlgItemMessage,hWin,103,WM_SETTEXT, 0, OFFSET lpbData+NULL
INVOKE SendDlgItemMessage,hWin,105,WM_SETTEXT, 0, DWORD PTR [lpbIP]+NULL
INVOKE SendDlgItemMessage,hWin,107,WM_SETTEXT, 0, DWORD PTR [str1]+NULL
Also, until I can get "str1" setup correctly, I've commented out that last 'INVOKE' that contains "str1" (you must've un-commented it out in your quote).
I guess I'm just going to have to do this old fashion way and build my own subroutine.
Thanks,
-Shooter
It is very simple to use szMultiCat:
invoke szMultiCat, NumberOfStringsToAppend, BufferForStrings, Addr String1, Addr String2, Addr String3 etc...
So for NumberOfStringsToAppend in the above sample you would put 3 because you are pushing 3 items on the stack..
BufferForString is a pointer to a buffer to hold the strings
So, off the top of my head for 3 string you might do:
invoke szLen, addr String1
mov ebx, eax
invoke szLen, addr String2
add ebx, eax
invoke szLen, addr String3
add ebx, eax
invoke HeapAlloc, hMainHeap, HEAP_ZERO_MEMORY, ebx
mov lpszTempMem, eax
invoke szMultiCat, 3, lpszTempMem, Addr String1, Addr String2, Addr String3
PrintStringByAddr lpszTempMem ; <----- handy debug macro that will print the string in a debug window
invoke HeapFree, hMainHeap, 0, lpszTempMem
DOH!!!!!!!
It might help if I added
mov second, ustr$(eax)
to my code. :red :red :red
Fixed it for you
I made the buffers oversized, you can fix all that
Right you wanted to display the time? It does, I commented out other stuff, you can fix all that yourself :bg
Shooter,
i might mention - Dr Watson and c0000005
when you see this, you can't help but being a little disappointed
but - get used to it
warm up to it
make it your friend :bg
sometimes, it can give you an offset or a stack value that helps you debug your code
and - it's better than the BSOD alternative
when i first started out in here, i considered changing my nic to c0000005 :lol
Quote from: Shooter on December 28, 2010, 07:50:22 PM
As I am making a call to a macro that makes another call to another macro that invokes szmulticat, I have no idea how to set those parameters.
Study the macros you are using. Or forget the M in Masm and code like in the 1980ies.
include \masm32\include\masm32rt.inc
.data
My$ dd txMyString
txMyString db "Good morning, this is Masm32!", 0
.data?
buffer db 1024 dup(?)
.code
start:
inkey cat$(offset buffer, "This is a cat$: [", My$, "]")
exit
end start
There are also more advanced macros around:
Print CrLf$, "Hello, it is now roughly ", Left$(Time$, 5), " on ", Date$, CrLf$, "time to go to bed", 13, 10
MsgBox 0, Cat$("Hello, it is now roughly "+Left$(Time$, 5)+" on "+Date$+CrLf$+"time to go to bed"), "Hi", MB_OK
:wink
Quote Print...
..., MB_OK
huh ? :eek
j/k Jochen :P
Shooter - JJ is the man when it comes to macros, around here :U
Quote from: Gunner on December 28, 2010, 08:27:21 PM
Fixed it for you
I made the buffers oversized, you can fix all that
Right you wanted to display the time? It does, I commented out other stuff, you can fix all that yourself :bg
Rob, I seriously appreciate that of you. I inserted your changes in place of my code's section and gave it a try... it works, but there's some gibberish being displayed at the beginning of TimeStr2. I'm trying to track down why right now.
-Shooter
I will tell you why.... the buffers are declared on the stack, you have to zero them, I did not do that
lookup memfill in the masm library help file
Quote from: dedndave on December 28, 2010, 08:41:14 PM
Quote Print...
..., MB_OK
huh ? :eek
j/k Jochen :P
Shooter - JJ is the man when it comes to macros, around here :U
It has been a very long time since I've even seen a macro for assembler, let alone how to use one. Adding dialog boxes to the mix really can strain one's own sanity when they don't have the memory they once used to. :dazzled:
I appreciate all the input.
The funny thing was, I just simply forgot to convert the "seconds" to text before calling cat$. Ooops, my bad. ;)
-Shooter
Rob,
I used memfill as you suggested and it works beautifully. Problem though, perhaps this isn't the method of getting the time I really want. I'd like for the clock to be updated on a regular basis so that the seconds and minutes are current. How would I do that?
-Shooter
Quote from: Gunner on December 28, 2010, 08:45:33 PM
I will tell you why.... the buffers are declared on the stack, you have to zero them, I did not do that
lookup memfill in the masm library help file
For use with cat$, it's sufficient to zero the first byte
include \masm32\include\masm32rt.inc
.code
AppName db "Masm32 is great!", 0
Hello db "A message:", 0
MyTest proc uses esi edi arg1:DWORD, arg2:DWORD
LOCAL locbuf[260]:BYTE
lea edi, locbuf
mov byte ptr [edi], 0
mov esi, cat$(edi, "This is the text: [", arg1, "]")
MsgBox 0, esi, arg2, MB_OK
ret
MyTest endp
start: invoke MyTest, offset AppName, addr Hello
exit
end start
That is cool to know jj :U .... personally I don't use macros (maybe one day I will get around to trying to create and use em) But he changed to using szMultCat, so I told him how to clear the garbage out of the buffer :wink
Shooter, search the board for WM_TIMER and SetTimer
Basically, you would create a timer with settimer with an interval of 1000 (for 1 second) and in your window proc you will get a WM_TIMER message every second (or whatever you set the interval for) and in WM_TIMER you would update the time...
Just for fun....
include \masm32\include\masm32rt.inc
.code
start: .Repeat
print "Current time is "
print time$(), 13
invoke Sleep, 500
invoke GetKeyState, VK_SHIFT
test ax, ax
.Until Sign?
print chr$(13, 10, "bye")
invoke Sleep, 1000
exit
end start
Quote from: Gunner on December 28, 2010, 10:48:37 PM
Basically, you would create a timer with settimer with an interval of 1000 (for 1 second) and in your window proc you will get a WM_TIMER message every second (or whatever you set the interval for) and in WM_TIMER you would update the time...
Rob,
I got it to work using SetTimer and WM_TIMER, but I noticed two things about it.
1) The text doesn't display immediately when the dialog appears (takes about a second), which is OK for now,
2) I noticed that if the minutes and / or seconds are less than 10, there isn't a leading zero. I'm not sure how to ensure there is.
-Shooter
you'll have to give us the EXE :P
we don't have E:\radasm - lol
also, we DO have
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\Comctl32.inc
include \masm32\include\shell32.inc
include \masm32\include\gdi32.inc
include \masm32\include\advapi32.inc
include \masm32\include\wsock32.inc
include \masm32\include\msvcrt.inc
include \masm32\include\MASM32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\Comctl32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\wsock32.lib
includelib \masm32\lib\msvcrt.lib
includelib \masm32\lib\MASM32.lib
i know - there are environment variables
but the "forum standard" is not to use them
i guess, to make it update immediately, you can use SendMessage when the event occurs to force an update
well - that's one way to do it
<<<<<--------------------------- also a n00b :bg
I'm not gonna do it all for you :toothy
In WM_INITDIALOG, you should get and show the time so it displays when the dialog loads, to update it you do what you are doing already in WM_TIMER... What would you do with code that you are going to call from multiple places? The answer.... next month :bg No, put the code you get and format the date/time and stick it in a proc and call that proc in WM_TIMER and in WM_INITDIALOG or just copy the code you have in WM_TIMER and paste it into WM_INITDIALOG, :bg
The time updates every second for me, BUT if for somereason it does not on another OS, you could do:
invoke GetDlgItem, hWin, 108
invoke InvalidateRgn, eax, NULL, TRUE
BTW, for readability and ease of code maintenance, you should NOT use the resource ID's you should use equates, STC_TIME equ 108 .... you can export the names in RadASM
I missed one of you questions Shooter, about a leading zero? Look up GetTimeFormat :bg
Instead of the code you where using just use the following:
;invoke GetLocalTime,ADDR LocalTime
invoke GetTimeFormat,LOCALE_USER_DEFAULT, NULL, NULL, offset TimeFormat, addr TimeStr2, 72
; movzx ecx, LocalTime.wHour
; invoke dwtoa, ecx, addr lpszHour
; movzx ecx, LocalTime.wMinute
; invoke dwtoa, ecx, addr lpszMinute
; movzx ecx, LocalTime.wSecond
; invoke dwtoa, ecx, addr lpszSecond
; invoke szMultiCat, 5, addr TimeStr2, addr lpszHour, offset szColon, \
; addr lpszMinute, offset szColon, addr lpszSecond
INVOKE SendDlgItemMessage,hWin,108,WM_SETTEXT, 0, addr TimeStr2
invoke GetDlgItem, hWin, 108
invoke InvalidateRgn, eax, NULL, TRUE
:U
Rob,
I'll have to look at it when I get back... got a party to go to. :bg
Thanks,
-Shooter
EDIT: Alright, I have a few minutes to look at this. ROB!! YOU RAWK!!! That worked out perfectly, and it seems so much cleaner too. Thanks. "I don't care what the other kids write about you on the bathroom stalls, you're alright!"
QuoteI don't care what the other kids write about you on the bathroom stalls...
yah, but at least i didn't put his phone number
Quote from: dedndave on December 29, 2010, 01:33:33 AM
QuoteI don't care what the other kids write about you on the bathroom stalls...
yah, but at least i didn't put his phone number
Um, I was told that it WAS you Dave. I forgotten all about that :toothy
Glad it helped Shooter
Haven't been a kid in a few decades... so I don't know who those "kids" are
Regarding the current time, I HAD it working perfectly until I resized the client area... now, for the first second it displays perfectly, but after that there is gibberish AFTER the displayed time and I can't understand what I did to cause that. Any ideas?ee
Update: I had also added a bitmap image, but forgot to set the settings to .BMP instead of .ICO. Not really sure why that caused my issue, but it's fixed now.
-Shooter