Problem with indexed adressing mode

Started by Bieb, February 02, 2005, 09:25:06 PM

Previous topic - Next topic

Bieb

I've been trying to create an app that takes a file and a key file.  It then takes a byte from the first file, and searches the key file for the same byte.  When it finds a byte that matches, it writes the adress of that byte to an output file.  It then repeats with the next byte.  The output file, apparently meaningless, is actually just a list of adresses, and when the bytes at those adresses are taken from the key file, they will reconstruct the original file.  To avoid using the same adress over and over for a byte, I've tried to set up a system where I keep an array of 256 DWORDs.  At the starting adress of that array, plus 4 * the byte being looked for, is kept the last location that byte was found in.  The next time it looks for that byte, it will start at the byte after that one, so that it can get to a different byte the next time.  I'm trying to used the indirect adressing  mode to access elements of the array, but whenever I try to use [eax] as and operand to the Mov instruction, I get an invalid instruction operands error.  Can anyone figure out why?  Here's the code I'm using.


.Const

.Data?
Edit1Handle DWord ?
Edit2Handle DWord ?
Edit3Handle DWord ?
LookFor Byte ?
CheckAgainst Byte ?
TrashDW DWord ?

.Data
FilePath1 DB 257 Dup (0)
FilePath2 DB 257 Dup(0)
FilePath3 DB 257 Dup(0)
ByteAdress DD 256 Dup (0)
ofn OPENFILENAME <>
FilterString DB "All Files", 0, "*.*", 0, 0
ErrorText DB "Error", 0
LookIn DD 0

.Code

Window1Procedure Proc Private hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
.If uMsg == WM_CREATE
Invoke GetWindowItem, hWnd, IDC_WINDOW1_EDIT1
Mov Edit1Handle, Eax
Invoke GetWindowItem, hWnd, IDC_WINDOW1_EDIT2
Mov Edit2Handle, Eax
Invoke GetWindowItem, hWnd, IDC_WINDOW1_EDIT3
Mov Edit3Handle, Eax
;Initialize the OFN API structure
Mov ofn.lStructSize, SizeOf ofn
        push hWnd
        Pop ofn.hWndOwner
        Invoke GetModuleHandle, NULL
        Mov ofn.hInstance, Eax
        Mov ofn.lpstrFilter, Offset FilterString
        Mov ofn.lpstrFile, Offset FilePath1
        Mov ofn.nMaxFile, 257
.ElseIf uMsg == WM_CLOSE
Invoke IsModal, hWnd
.If Eax
Invoke EndModal, hWnd, IDCANCEL
Return TRUE
.EndIf
.ElseIf uMsg == WM_COMMAND
Mov Eax, wParam
.If Ax == IDC_WINDOW1_ENCBUTTON
Shr Eax, 16
.If Ax == BN_CLICKED
;Code to execute if encode button has been clicked
Invoke GetWindowText, Edit1Handle, Addr FilePath1, 257
Invoke GetWindowText, Edit2Handle, Addr FilePath2, 257
Invoke GetWindowText, Edit3Handle, Addr FilePath3, 257
Invoke EncodeFile
.EndIf
.ElseIf Ax == IDC_WINDOW1_DECBUTTON
Shr Eax, 16
.If Ax == BN_CLICKED
;Code to execute if the decode button has been clicked
Invoke GetWindowText, Edit1Handle, Addr FilePath1, 257
Invoke GetWindowText, Edit2Handle, Addr FilePath2, 257
Invoke GetWindowText, Edit3Handle, Addr FilePath3, 257
Invoke DecodeFile
.EndIf
.ElseIf Ax == IDC_WINDOW1_BROWSE1
Shr Eax, 16
.If Ax == BN_CLICKED
;Code to execute if the first browse button has been clicked
Mov ofn.lpstrFile, Offset FilePath1
Mov ofn.Flags, OFN_FILEMUSTEXIST Or \
                                OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                                OFN_EXPLORER or OFN_HIDEREADONLY
                Invoke GetOpenFileName, Addr ofn
                .If Eax == TRUE
                Invoke SetWindowText, Edit1Handle, Addr FilePath1
            .EndIf
.EndIf
.ElseIf Ax == IDC_WINDOW1_BROWSE2
Shr Eax, 16
.If Ax == BN_CLICKED
;Code to execute if the second browse button has been clicked
Mov ofn.lpstrFile, Offset FilePath2
Mov ofn.Flags, OFN_FILEMUSTEXIST Or \
                                OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                                OFN_EXPLORER or OFN_HIDEREADONLY
                Invoke GetOpenFileName, Addr ofn
                .If Eax == TRUE
                Invoke SetWindowText, Edit2Handle, Addr FilePath2
            .EndIf
.EndIf
.ElseIf Ax == IDC_WINDOW1_BROWSE3
Shr Eax, 16
.If Ax == BN_CLICKED
;Code to execute if the third browse button has been clicked
Mov ofn.lpstrFile, Offset FilePath3
Mov ofn.Flags, OFN_FILEMUSTEXIST Or \
                                OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                                OFN_EXPLORER or OFN_HIDEREADONLY
                Invoke GetOpenFileName, Addr ofn
                .If Eax == TRUE
                Invoke SetWindowText, Edit3Handle, Addr FilePath3
            .EndIf
.EndIf
.EndIf
.EndIf
Return FALSE
Window1Procedure EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;Procedure to encode a file
EncodeFile Proc
;Local variable definitions
Local F1Handle:DWord
Local F2Handle:DWord
Local F3Handle:DWord
Local F1Size:DWord
Local F2Size:DWord
Local CurrentByte:DWord
Local Found:Byte

;Open files
Invoke CreateFile, Addr FilePath1, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
.If Eax == 0
Jmp EncError
.Else
Mov F1Handle, Eax
.EndIf
Invoke CreateFile, Addr FilePath2, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
.If Eax == 0
Jmp EncError
.Else
Mov F2Handle, Eax
.EndIf
Invoke CreateFile, Addr FilePath3, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
.If Eax == 0
Jmp EncError
.Else
Mov F3Handle, Eax
.EndIf

;Get file sizes
Invoke GetFileSize, F1Handle, Addr TrashDW
.If Eax == 0
Jmp EncError
.ElseIf Eax == -1
Jmp EncError
.Else
Mov F1Size, Eax
.EndIf
Invoke GetFileSize, F2Handle, Addr TrashDW
.If Eax == 0
Jmp EncError
.ElseIf
Jmp EncError
.Else
Mov F2Size, Eax
.EndIf

;Begin encoding loop
Mov Eax, F1Size
.While CurrentByte < Eax
Invoke ReadFile, F1Handle, Addr LookFor, 1, NULL, NULL
Xor Eax, Eax
Mov Ah, LookFor
Mov Al, 4
Mul Ah
Add Eax, Offset ByteAdress
Mov LookIn, [Eax]
Mov Found, 0
.While Found == 0
Invoke SetFilePointer, F2Handle, LookIn, NULL, FILE_BEGIN
Invoke ReadFile, F2Handle, Addr CheckAgainst, 1, NULL, NULL
Mov Al, CheckAgainst
.If LookFor == Al
Invoke WriteFile, F3Handle, Addr LookIn, 4, NULL, NULL
Mov Found, 1
Add LookIn, 1
Xor Eax, Eax
Mov Ah, LookFor
Mov Al, 4
Mul Ah
Add Eax, Offset ByteAdress
Mov [Eax], LookIn
.EndIf
Add LookIn, 1
.EndW
.EndW

;Exit code
Jmp EncExit
EncError:
Invoke MessageBox, NULL, Addr ErrorText, Addr ErrorText, MB_OK
EncExit:
Ret
EncodeFile EndP

;Procedure to decode a file
DecodeFile Proc

Ret
DecodeFile EndP


Ramon Sala

Hi Bieb,

I do not know exactly why, but MASM does not allow this type of indexed addressing:

      Add Eax, Offset ByteAdress
      Mov LookIn, [Eax]
      Mov Found, 0


Instead you should use a register (i.e. Eax) like this:

      Add Eax, Offset ByteAdress
      Mov Eax, [Eax]
      Mov LookIn, Eax

      Mov Found, 0

Ramon
Greetings from Catalonia

Ramon Sala

#2
Bieb,

I attach a zipped help file where there is some information about addressing. Once unzipped, see topic Addressing and Pointers. I hope it can help you.


Ramon


[attachment deleted by admin]
Greetings from Catalonia

Bieb

Is this a quirk of MASM, or does the CPU simply not support that kind of adressing?

Ramon Sala

Well, when I said MASM I really meant the Intel x86 CPU.
Greetings from Catalonia

Bieb

Same project, new problem.  I realized that there's no need to store old filepointers, and that if I just pick up the filepointer where it is, it'll end up looking in pseudo random locations all on it's own.  So, I've finally gotten code written that looks like it should successfully encode a file, but when I try to encode a file, it returns a runtime error "C0000005H - Access violation write" error.  What's that supposed to mean?  Here's the code, and I've attached the entire project.


.Const

.Data?
Edit1Handle DWord ?
Edit2Handle DWord ?
Edit3Handle DWord ?
LookFor Byte ?
CheckAgainst Byte ?
TrashDW DWord ?
FilePointer DWord ?
CurrentByte DWord ?

.Data
FilePath1 DB 257 Dup (0)
FilePath2 DB 257 Dup(0)
FilePath3 DB 257 Dup(0)
ByteAdress DB 256 Dup (0)
ofn OPENFILENAME <>
FilterString DB "All Files", 0, "*.*", 0, 0
ErrorText DB "Error", 0
LookIn DD 0
Done DB "Done" , 0

.Code

Window1Procedure Proc Private hWnd:HWND, uMsg:ULONG, wParam:WPARAM, lParam:LPARAM
.If uMsg == WM_CREATE
Invoke GetWindowItem, hWnd, IDC_WINDOW1_EDIT1
Mov Edit1Handle, Eax
Invoke GetWindowItem, hWnd, IDC_WINDOW1_EDIT2
Mov Edit2Handle, Eax
Invoke GetWindowItem, hWnd, IDC_WINDOW1_EDIT3
Mov Edit3Handle, Eax
;Initialize the OFN API structure
Mov ofn.lStructSize, SizeOf ofn
        push hWnd
        Pop ofn.hWndOwner
        Invoke GetModuleHandle, NULL
        Mov ofn.hInstance, Eax
        Mov ofn.lpstrFilter, Offset FilterString
        Mov ofn.lpstrFile, Offset FilePath1
        Mov ofn.nMaxFile, 257
.ElseIf uMsg == WM_CLOSE
Invoke IsModal, hWnd
.If Eax
Invoke EndModal, hWnd, IDCANCEL
Return TRUE
.EndIf
.ElseIf uMsg == WM_COMMAND
Mov Eax, wParam
.If Ax == IDC_WINDOW1_ENCBUTTON
Shr Eax, 16
.If Ax == BN_CLICKED
;Code to execute if encode button has been clicked
Invoke GetWindowText, Edit1Handle, Addr FilePath1, 257
Invoke GetWindowText, Edit2Handle, Addr FilePath2, 257
Invoke GetWindowText, Edit3Handle, Addr FilePath3, 257
Invoke EncodeFile
.EndIf
.ElseIf Ax == IDC_WINDOW1_DECBUTTON
Shr Eax, 16
.If Ax == BN_CLICKED
;Code to execute if the decode button has been clicked
Invoke GetWindowText, Edit1Handle, Addr FilePath1, 257
Invoke GetWindowText, Edit2Handle, Addr FilePath2, 257
Invoke GetWindowText, Edit3Handle, Addr FilePath3, 257
Invoke DecodeFile
.EndIf
.ElseIf Ax == IDC_WINDOW1_BROWSE1
Shr Eax, 16
.If Ax == BN_CLICKED
;Code to execute if the first browse button has been clicked
Mov ofn.lpstrFile, Offset FilePath1
Mov ofn.Flags, OFN_FILEMUSTEXIST Or \
                                OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                                OFN_EXPLORER or OFN_HIDEREADONLY
                Invoke GetOpenFileName, Addr ofn
                .If Eax == TRUE
                Invoke SetWindowText, Edit1Handle, Addr FilePath1
            .EndIf
.EndIf
.ElseIf Ax == IDC_WINDOW1_BROWSE2
Shr Eax, 16
.If Ax == BN_CLICKED
;Code to execute if the second browse button has been clicked
Mov ofn.lpstrFile, Offset FilePath2
Mov ofn.Flags, OFN_FILEMUSTEXIST Or \
                                OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                                OFN_EXPLORER or OFN_HIDEREADONLY
                Invoke GetOpenFileName, Addr ofn
                .If Eax == TRUE
                Invoke SetWindowText, Edit2Handle, Addr FilePath2
            .EndIf
.EndIf
.ElseIf Ax == IDC_WINDOW1_BROWSE3
Shr Eax, 16
.If Ax == BN_CLICKED
;Code to execute if the third browse button has been clicked
Mov ofn.lpstrFile, Offset FilePath3
Mov ofn.Flags, OFN_FILEMUSTEXIST Or \
                                OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                                OFN_EXPLORER or OFN_HIDEREADONLY
                Invoke GetSaveFileName, Addr ofn
                .If Eax == TRUE
                Invoke SetWindowText, Edit3Handle, Addr FilePath3
            .EndIf
.EndIf
.EndIf
.EndIf
Return FALSE
Window1Procedure EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;Procedure to encode a file
EncodeFile Proc
;Local variable definitions
Local F1Handle:DWord
Local F2Handle:DWord
Local F3Handle:DWord
Local F1Size:DWord
Local F2Size:DWord
Local Found:Byte

;Open files
Invoke CreateFile, Addr FilePath1, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
.If Eax == 0
Jmp EncError
.Else
Mov F1Handle, Eax
.EndIf
Invoke CreateFile, Addr FilePath2, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
.If Eax == 0
Jmp EncError
.Else
Mov F2Handle, Eax
.EndIf
Invoke CreateFile, Addr FilePath3, GENERIC_WRITE Or GENERIC_READ, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
.If Eax == 0
Jmp EncError
.Else
Mov F3Handle, Eax
.EndIf

;Get file sizes
Invoke GetFileSize, F1Handle, Addr TrashDW
.If Eax == 0
Jmp EncError
.ElseIf Eax == -1
Jmp EncError
.Else
Mov F1Size, Eax
.EndIf
Invoke GetFileSize, F2Handle, Addr TrashDW
.If Eax == 0
Jmp EncError
.ElseIf Eax == -1
Jmp EncError
.Else
Mov F2Size, Eax
.EndIf

;Begin encoding loop
Mov CurrentByte, 0
Mov Eax, F1Size
.While CurrentByte < Eax
Invoke ReadFile, F1Handle, Addr LookFor, 1, NULL, NULL
Mov Found, 0
.While Found == 0
Mov Eax, FilePointer
.If Eax > F2Size
Mov FilePointer, 0
Invoke SetFilePointer, F2Handle, 0, NULL, FILE_BEGIN
.EndIf
Invoke ReadFile, F2Handle, Addr CheckAgainst, 1, NULL, NULL
Mov Al, CheckAgainst
.If Al == LookFor
Mov Found, 1
Invoke WriteFile, F3Handle, Addr FilePointer, 4, NULL, NULL
.EndIf
Inc FilePointer
.EndW
Inc CurrentByte
Mov Eax, F1Size
.EndW
Invoke CloseHandle, F1Handle
Invoke CloseHandle, F2Handle
Invoke CloseHandle, F3Handle
Invoke MessageBox, NULL, Addr Done, Addr Done, MB_OK

;Exit code
Jmp EncExit
EncError:
Invoke MessageBox, NULL, Addr ErrorText, Addr ErrorText, MB_OK
EncExit:
Ret
EncodeFile EndP

;Procedure to decode a file
DecodeFile Proc

Ret
DecodeFile EndP

[attachment deleted by admin]

Ramon Sala

#6
Hi Bieb,

I attach your project with some modifications. First of all have a look at API help for ReadFile/WriteFile functions. As it says, when the 'lpOverlapped' parameter (the last one) is NULL, 'lpNumberOfBytesRead' ('lpNumberOfBytesWritten for WriteFile') cannot be NULL. That caused the memory write violation, so I added a Local DWord varialble in the EncodeFile procedure (dwBytes in line 128) to pass its address as the fourth parameter of ReadFile/WriteFile functions (modified lines 175, 191 and 198). That solved the memory access violation, but doing some checking with your own Test.txt files (Test.txt, Test2.txt), I realized that the inside loop never ended and the application crashed. To avoid that, I added a Jump (line 186) to exit the loop when the key file arrives to the end. Now your application doesn't crash, but you have to check if it encodes properly.

Ramon


[attachment deleted by admin]
Greetings from Catalonia

Bieb

Thanks for the help.  I've finished up the encoding and decoding routines, so all that's left is to add a progress bar.  For anyone who's interested, I've attached the almost finished version.

[attachment deleted by admin]