The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Shooter on December 28, 2010, 06:48:59 PM

Title: Access Violation??
Post by: Shooter on December 28, 2010, 06:48:59 PM
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.
Title: Re: Access Violation??
Post by: Gunner on December 28, 2010, 07:02:07 PM
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
Title: Re: Access Violation??
Post by: dedndave on December 28, 2010, 07:04:14 PM
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
Title: Re: Access Violation??
Post by: qWord on December 28, 2010, 07:12:52 PM
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.
Title: Re: Access Violation??
Post by: Shooter on December 28, 2010, 07:16:38 PM
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
Title: Re: Access Violation??
Post by: qWord on December 28, 2010, 07:20:43 PM
Quote from: Shooter on December 28, 2010, 07:16:38 PMWhere did you find that quote?
look at \masm32\help\hlhelp.chm

qWord
Title: Re: Access Violation??
Post by: Shooter on December 28, 2010, 07:35:40 PM
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)
Title: Re: Access Violation??
Post by: 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.
Title: Re: Access Violation??
Post by: Shooter on December 28, 2010, 07:50:22 PM
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
Title: Re: Access Violation??
Post by: dedndave on December 28, 2010, 07:58:32 PM
   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
Title: Re: Access Violation??
Post by: Shooter on December 28, 2010, 08:08:31 PM
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
Title: Re: Access Violation??
Post by: Gunner on December 28, 2010, 08:12:41 PM
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
Title: Re: Access Violation??
Post by: Shooter on December 28, 2010, 08:17:17 PM
DOH!!!!!!!

It might help if I added
    mov second, ustr$(eax)
to my code. :red :red :red
Title: Re: Access Violation??
Post by: 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
Title: Re: Access Violation??
Post by: dedndave on December 28, 2010, 08:29:07 PM
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
Title: Re: Access Violation??
Post by: jj2007 on December 28, 2010, 08:37:49 PM
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
Title: Re: Access Violation??
Post by: 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
Title: Re: Access Violation??
Post by: Shooter on December 28, 2010, 08:44:02 PM
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
Title: Re: Access Violation??
Post by: 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
Title: Re: Access Violation??
Post by: Shooter on December 28, 2010, 08:48:34 PM
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
Title: Re: Access Violation??
Post by: Shooter on December 28, 2010, 10:01:54 PM
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
Title: Re: Access Violation??
Post by: jj2007 on December 28, 2010, 10:31:11 PM
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

Title: Re: Access Violation??
Post by: Gunner on December 28, 2010, 10:48:37 PM
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...
Title: Re: Access Violation??
Post by: jj2007 on December 28, 2010, 11:17:56 PM
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
Title: Re: Access Violation??
Post by: Shooter on December 28, 2010, 11:48:29 PM
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
Title: Re: Access Violation??
Post by: dedndave on December 28, 2010, 11:57:12 PM
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
Title: Re: Access Violation??
Post by: dedndave on December 28, 2010, 11:59:24 PM
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
Title: Re: Access Violation??
Post by: Gunner on December 29, 2010, 12:00:05 AM
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
Title: Re: Access Violation??
Post by: Gunner on December 29, 2010, 12:04:20 AM
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
Title: Re: Access Violation??
Post by: Gunner on December 29, 2010, 12:13:47 AM
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
Title: Re: Access Violation??
Post by: Shooter on December 29, 2010, 01:15:59 AM
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!"
Title: Re: Access Violation??
Post by: 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
Title: Re: Access Violation??
Post by: Gunner on December 29, 2010, 01:44:03 AM
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
Title: Re: Access Violation??
Post by: Shooter on February 12, 2011, 09:20:05 PM
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