The MASM Forum

Projects => Rarely Used Projects => GoAsm => Topic started by: shankle on March 22, 2013, 12:11:54 AM

Title: can't get this code to work on 64-bit GoAsm
Post by: shankle on March 22, 2013, 12:11:54 AM
PtrMem                  dd       0   
hMemory                dd       0
FileSize                  dd       0
BytesRead              dd       0
hFile                      dd       0

          invoke GlobalLock, [hMemory]
          mov [PtrMem],eax               
          invoke ReadFile, [hFile],[PtrMem],[FileSize],addr BytesRead,NULL
         
          mov ebx,[PtrMem]             ; Points ebx to 1st record of data in memory         
       **   mov al,B[ebx]  **

This code works in 32-bit GoAsm.  I made the proper changes to the DDs and code
but it won't work in 64-bit GoAsm.
The error seems to occur at "mov al,B[ebx]"
Thanks for any help.
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: dedndave on March 22, 2013, 12:17:48 AM
hi Jack
you probably want to use 64-bit addresses in 64-bit code
mov al,B[rbx]

        mov rbx,[PtrMem]             ; Points rbx to 1st record of data in memory         
        mov al,B[rbx]

Title: Re: can't get this code to work on 64-bit GoAsm
Post by: shankle on March 22, 2013, 01:12:53 AM
PtrMem                dq       0   
hMemory              dq       0
FileSize                dq       0
BytesRead            dq       0
hFile                    dq       0
     
          invoke GlobalAlloc, GHND,[FileSize]
          mov [hMemory],rax
          invoke GlobalLock, [hMemory]
          mov [PtrMem],rax
               
          invoke ReadFile, [hFile],[PtrMem],[FileSize],addr BytesRead,NULL
          mov rbx,[PtrMem]             ; Points rbx to 1st record of data in memory
                 
     **   mov al,B[rbx] **   
     
This code does not work in 64-bit GoAsm
My previous ex: above works in 32-bit GoAsm         
The offending line is "mov al,B[rbx]" (I think)
At least that is where it fails.
Purpose is to get a byte of data to compare to something else
Thanks for any help....
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: dedndave on March 22, 2013, 01:29:29 AM
you have BytesRead defined twice   :P
it should be a qword

verify [FileSize] is not zero before you call GlobalAlloc

i don't think GPTR is appropriate for memory you are going to lock
use GHND

or, use GPTR and do not lock it

i only use GlobalLock when an operation specifically requires it - like using the clipboard
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: shankle on March 25, 2013, 03:10:00 PM
mov al,B[ebx] works in 32-bit

mov al,B[rbx]  does not work in 64-bit

see the 2 examples above for clarification.
Tried to use the 32-bit code in the 64-bit program and of course
that doesn't work.
What I want to do is get a byte of data from memory into "al".
Thanks for any help.......
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: dedndave on March 25, 2013, 06:55:08 PM
when you say "it doesn't work" - we don't really know what that means
we don't know if it throws an assembly error or a runtime error
and - it would help to have details of the error type (error codes help a lot)

however, there are a few possibilities that i can think of as to why you might experience trouble
1) RBX is not pointing to the "array" in the data section
2) RBX needs to be preserved across many calls, according to the ABI
3) you are trying to use a 64-bit address in a 32-bit build
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: shankle on March 25, 2013, 11:37:51 PM
Hi Dave,
Thanks for helping.
No assembly errors, No run time errors, No error codes
It is a 64-bit setup
rbx is pointed to a file in memory and the file is there.
I have a messagebox before "mov al,B[rbx]" and it executes the messagebox.
If I move the messagebox after "mov al,B[rbx]" I get a blue screen and a window
stating that the program has stopped working. If I expand the details I get a useless
Microsoft message "Problem event name "bex64".
This leaves me dead in the water......
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: dedndave on March 26, 2013, 12:04:35 AM
did a little googling on BEX64....
it seems that an error report is generated and placed in C:\LocalDumps (something like that)
perhaps it will shed more light on it
maybe you can find the one generated by your program and attach it
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: dedndave on March 26, 2013, 12:55:49 AM
hi Jack - me again   :P

i was reading up on DEP at ms technet
http://technet.microsoft.com/en-us/library/cc738483%28v=ws.10%29.aspx (http://technet.microsoft.com/en-us/library/cc738483%28v=ws.10%29.aspx)

it sounds to me as though we have not resolved the allocation pointer issue for 64-bit code
you may be able to avoid the crashes by checking the return value of GlobalAlloc

for what you are doing, i think GPTR is the best option
if you use that flagset, you do not need to use GlobalLock or GlobalUnlock
        INVOKE  GlobalAlloc,GPTR,[FileSize]
        mov     [PtrMem],rax
        or      rax,rax
        jz      Memory_not_allocated

the return value will either be 0 or a pointer to the allocated block
if it is 0, it means the allocation failed - do not try to access the buffer

if you choose to use GlobalLock and GlobalUnlock, then you want to use the GHND flagset
        INVOKE  GlobalAlloc,GHND,[FileSize]
        mov     [hMemory],rax
        or      rax,rax
        jz      Memory_not_allocated

        INVOKE  GlobalLock,rax
        mov     [PtrMem],rax
        or      rax,rax
        jz      Memory_not_locked

again, if GlobalAlloc or GlobalLock return 0, do not try to access the buffer
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: dedndave on March 26, 2013, 01:09:37 AM
a little more thought.....

not sure you really need to zero-init the allocated block
it is faster if you do not
just use GMEM_FIXED, and no lock/unlock   :P

actually, i would probably use HeapAlloc - lol
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: shankle on March 26, 2013, 03:01:28 AM
Hi Dave,
I tried the Heapcreate as you see below.
The value in HeapAlloc is a variable number. So I don't see how that
would work.
HeapCreate executed without an error.
HeapAlloc never executes .n1 and gives a blue screen
with Microsofts "AppCrash" message in the details.
The other HeapAlloc return values did not appear.
My testmsg3 never gets executed.

PtrMem           dq  0
HeapHandle    dq  0

          invoke HeapCreate HEAP_GENERATE_EXCEPTIONS.120000,0 
          mov [HeapHandle],rax
         
          invoke HeapAlloc [HeapHandle],HEAP_GENERATE_EXCEPTIONS,120000
          mov [PtrMem],rax
          or   rax,rax
          jz >>.n1
         
;test code begin
;testmsg3    db  'after HeapAlloc',0
        invoke MessageBox, [hWnd], addr testmsg3, addr testmsg3, MB_OK ;true
; test code end           

; other code

.n1
;test code begin
;testmsg7    db  'memory not allocated',0
        invoke MessageBox, [hWnd], addr testmsg7, addr testmsg7, MB_OK ;true
; test code end
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: qWord on March 26, 2013, 03:56:02 AM
Quote from: shankle on March 26, 2013, 03:01:28 AMThe value in HeapAlloc is a variable number. So I don't see how that
would work.
Well, that is common for dynamic memory allocation.
Furthermore, you do not need to create a new heap: use the already existing process heap. The handle to that heap is returned through GetProcessHeap().
Also, if you use the flag HEAP_GENERATE_EXCEPTIONS there is no need to check the return value of HeapAlloc(), because that code will never executed in case of an error (you can catch the exception with an exception handler).
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: shankle on March 26, 2013, 06:56:33 AM
3-25-2013
For a 64-bit program.
The value in HeapAlloc is a variable number.
GetProcessHeap executed without an error.
HeapAlloc never executes the test code and gives a blue screen
with Microsofts "AppCrash" message in the details.
The other HeapAlloc return values did not appear.
My testmsg3 never gets executed.
Not sure if "mov [HeapHandle],rax" code is correct.


PtrMem        dq  0
HeapHandle    dq  0

          invoke GetProcessHeap 
          mov [HeapHandle],rax
          invoke HeapAlloc [HeapHandle],HEAP_GENERATE_EXCEPTIONS,120000
          mov [PtrMem],rax
         
;test code begin
testmsg3    db  'after HeapAlloc',0
        invoke MessageBox, [hWnd], addr testmsg3 addr testmsg3, MB_OK ;true
; test code end
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: qWord on March 26, 2013, 07:35:29 AM
did you define a string in the code section?
It may be simpler for us, if you reduce your code to show the problem and upload it with the executable.
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: dedndave on March 26, 2013, 08:47:23 AM
qWord has the right idea, Jack
here is what i suggest

first, let's create a couple message strings
        .DATA
SuccessMessage db 'Success',0
FailureMessage db 'Failure',0


use global variables for hHeap and PtrMem
        .DATA?
hHeap   dq ?
PtrMem  dq ?


during program initialization, get and store the process heap
        INVOKE  GetProcessHeap
        mov     [hHeap],rax


now, when you want to allocate and free memory, use hHeap, HeapAlloc, and HeapFree
        INVOKE  HeapAlloc,[hHeap],NULL,120000  ;replace NULL with HEAP_ZERO_MEMORY if needed
        mov     [PtrMem],rax
        or      rax,rax
        jz      Allocation_Error

;your "file read" code, here

        push    rbx
        mov     rbx,[PtrMem]

;let's test it

        mov     al,[rbx]

;other code, here

        pop     rbx

;free the allocated block, when done using it

        INVOKE  HeapFree,[hHeap],NULL,[PtrMem]
        INVOKE  MessageBox,0,addr SuccessMessage,addr SuccessMessage,MB_OK
        jmp     Done

Allocation_Error:
        INVOKE  MessageBox,0,addr FailureMessage,addr FailureMessage,MB_OK

Done:
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: shankle on March 26, 2013, 11:36:21 PM
To Dave,
I'm really doing the same thing as your last post but with different names.
To QWord,
Any  of my "testmsg" are defined in the GoAsm Data Section.

However I think I have found the culprit.
In Microsofts expansion of the blue screen window it is complaining about a module
called "ntdll.dll". Listed under Fault Module Name.
I have included a zip file of the window.

As far as I know my Windows 7 pro 64-bit is up to date.
Lot of stuff on the internet about this module but I am afraid to use it.
Usually you get more than you bargained for with these programs.
Ran Microsofts "sfc /scannow" and it showed no errors.
Have no idea how to proceed from this point.
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: dedndave on March 27, 2013, 01:40:35 AM
in that pic, the "Exception Code: c0000005" line tells you what the problem is
the "Exception Offset: 00000000000533dd" line tells you where, in your code, it occurs

c0000005 is an ACCESS_VIOLATION
it happens when you try to access memory in a section that does not have the proper attribute
this is quite often caused by accessing memory at an address of 0   :P
so, i am guessing that the allocation fails, and RBX = 0 when you try to read the byte
if you disassemble or debug your code, i bet you'll find the MOV AL,[RBX] instruction is at address 533ddh

write a little test program, using the code as i have it in my previous post
the exception should not occur   :t

i don't have a 64-bit machine, nor do i have GoAsm, or i would test it myself

there are a few differences in the code
for example, i use a flag of NULL, where you use generate exceptions
my code tests for success after the allocation
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: shankle on March 27, 2013, 01:57:55 AM
Ok Dave,
Will give it a whirl....
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: shankle on April 08, 2013, 01:14:48 AM
Thanks guys for helping.
As I have said before Globalalloc works in 32-bit GoAsm.
In 64-bit GoAsm neither Globalalloc or the Heap instructions work for me.
And I'll admit the problem is probably me.
So i tried another solution.
Defined a field as Blah1 db ?.
There seems to be a limit to the data that can be put in this field.
If I redefine Blah1 to Blah1  db 500000. This allows my entire source file to be read in.
The obvious reason for not wanting to do this the size of the executable file.
So I guess I am asking what is the limit of the size of an uninitialized field????
Title: Re: can't get this code to work on 64-bit GoAsm
Post by: wjr on April 08, 2013, 02:03:50 AM

ErrorLimit DB 04000000h DUP ? ;maximum, above this gives an error
WarningLimit DB 00100000h DUP ? ;above this gives a warning