News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

can't get this code to work on 64-bit GoAsm

Started by shankle, March 22, 2013, 12:11:54 AM

Previous topic - Next topic

shankle

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.

dedndave

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]


shankle

#2
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....

dedndave

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

shankle

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.......

dedndave

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

shankle

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......

dedndave

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

dedndave

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

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

dedndave

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

shankle

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

qWord

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).
MREAL macros - when you need floating point arithmetic while assembling!

shankle

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

qWord

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.
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

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: