Hi all, need some guidance in understanding how to make further progress
I am trying to invoke a procedure but the assembly fails with the A2071 error pointing at the last line (endp) of the procedure.
Attempts to comment out the bulk of the code is not helping and I am not sure what I am looking for ? The logic is not complete
as I cannot proceed without the ability to assemble - code specifics follow:
readrec PROTO :DWORD
invoke readrec, offset recout
readrec proc outbuf:dword
LOCAL hFile :DWORD ; file handle
LOCAL bwrt :DWORD ; variable for bytes written
LOCAL cloc :DWORD ; current location variable
LOCAL txt :DWORD ; text handle
LOCAL flen :DWORD ; file length variable
LOCAL hMem :DWORD ; allocated memory handle
LOCAL lbuf :DWORD ; address of line buffer
LOCAL inPtr :DWORD ; input buffer ptr
LOCAL otPtr :DWORD ; output buffer ptr
cmp hMem, 0 ; Check if file open
jne labGO ; Jump if so
mov hFile, fopen("testIN.asm") ; open the input file
mov flen, fsize(hFile) ; get its length
mov hMem, alloc(1024+1) ; allocate a 1k plus '0' buffer
mov eax, outbuf ; store passed line buffer
mov lbuf, eax ; store passed line buffer
mov inPtr, 0 ; reset input buffer ptr
mov otPtr, 0 ; reset output buffer ptr
labRD:
mov cloc, fseek(hFile,cloc,0) ; save next file pointer
mov bwrt, fread(hFile,hMem,1024) ; read data from file into buffer
labGO:
mov esi,hMem ; setup input buffer
mov edi,outbuf ; setup output line buffer
;========================= BUILD A NEW LINE =========================================
rdLine: ; Get Line
mov al,[esi] ; get next input char
inc esi ; incr in pointer
cmp al,13 ; check if CR char
je labCR ; go check for EoR
mov[edi],al ; store next output char
inc edi ; incr out pointer
jmp rdLine ; loop for next
;=======================================================================================
labCR: ; CR found
mov[edi],al ; store CR char
inc edi ; incr out pointer
mov al,[esi]
inc esi
cmp al,10 ; check if LF char
je labLF
labLF: ; LF found
mov[edi],al ; store LF char
inc edi ; incr out pointer
ret
readrec endp
your code compiles just fine here
How does the complete asm file being assembled look like ?
Many thanks for the prompt and thought provoking response.
Just to be clear are you saying that despite the assembler pointing to this proc as being in error
the actual problem could be elsewhere in the code?
Best,
As far as I've been able to compile it without warnings I thought that the actual problem lies outside this proc
Quote from: vertograd on March 25, 2014, 12:41:19 AM
your code compiles just fine here
Well, it doesn't, it throws plenty of errors - probably because the OP assumes that real experts like vertograd have nothing better to do than adding header stuff etc to his code.
include \masm32\include\masm32rt.inc
.code
start:
[OP's code]
end start
If you want feedback, post COMPLETE code.
Quote from: jj2007 on March 25, 2014, 03:00:13 AM
...
Well, it doesn't, it throws plenty of errors - probably because the OP assumes that real experts like vertograd have nothing better to do than adding header stuff etc to his code.
JJ, as I already wrote the code compiles fine HERE (you're not here, are you?) ;)
Really I'm not an expert and therefore I found some time to add all missing stuff and successfully assemble it .
[EDIT]: BTW I used ML 6.14 AND THE LATEST MASM32 PACK
Hi pgw001,
Quote from: pgw001 on March 25, 2014, 12:01:35 AM
I am trying to invoke a procedure but the assembly fails with the A2071 error pointing at the last line (endp) of the procedure.
Error A2071 is this (http://msdn.microsoft.com/en-us/library/aa712314%28v=vs.71%29.aspx). You should post the entire code for qualified help.
Gunther
Folks, thanks for your time and support
The assembler throws up the A2071 error pointing to the readrec endp statement - full code follows:
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\windows.inc ; always first
include \masm32\macros\macros.asm ; MASM support macros
; -----------------------------------------------------------------
; include files that have MASM format prototypes for function calls
; -----------------------------------------------------------------
include \masm32\include\masm32.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\msvcrt.inc ; C Runtime Library (CRT)
; ------------------------------------------------
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ------------------------------------------------
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\msvcrt.lib ; C Runtime Library (CRT)
include gwMacros.inc
.DATA ; Begin initialized data segment
; --------------------------
; PROTO statements for INVOKE
; --------------------------
show_text PROTO :DWORD
wtor PROTO :DWORD, :DWORD
strlen PROTO:PSTR
SetConRows PROTO :DWORD
system PROTO C, :PTR BYTE
readrec PROTO :DWORD
; --------------------------
; CONSOLE definitions
; --------------------------
txtmsg db "This is in the .DATA section",0 ; General display message
txtout db 'Enter input : ',0 ; Request input prompt
txtin dword 25 DUP(?) ; Console input buffer
txtlen dword ($-txtin) ; Console buffer size
CRLF DB 00Ah, 00Dh, 0 ; End of line
command BYTE "color 17",0 ; Set console Fore - white, Back - blue
commandw BYTE "mode CON: COLS=140" ; Set console column width
; --------------------------
; FILE definitions
; --------------------------
recout BYTE 160 DUP (?) ; Output record buffer
reclen dword ($-recout) ; Output record length
recptr PBYTE recout ; Output record pointer
hWriteto dd ? ; Device handle (Writefile)
ByteCnt dd ? ; Bytes written (Writefile)
.CODE ; Tell MASM where the code starts
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; < LOCAL MACROS
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
start:
INVOKE SetConRows,70 ; Resize Console window
invoke system, offset command ; set new back/fore colours
invoke system, offset commandw
call sub4 ; branch to Subroutine
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
sub4 proc
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; < SUB4 FILE I/O
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; -------------------------------------------------
; open the file read and display its content
; (RECORD OPTION)
; -------------------------------------------------
invoke readrec, offset recout
ret
sub4 endp
readrec proc outbuf:dword
LOCAL hFile :DWORD ; file handle
LOCAL bwrt :DWORD ; variable for bytes written
LOCAL cloc :DWORD ; current location variable
LOCAL txt :DWORD ; text handle
LOCAL flen :DWORD ; file length variable
LOCAL hMem :DWORD ; allocated memory handle
LOCAL lbuf :DWORD ; address of line buffer
LOCAL inPtr :DWORD ; input buffer ptr
LOCAL otPtr :DWORD ; output buffer ptr
cmp hMem, 0 ; Check if file open
jne labGO ; Jump if so
mov hFile, fopen("testIN.asm") ; open the input file
mov flen, fsize(hFile) ; get its length
mov hMem, alloc(1024+1) ; allocate a 1k plus '0' buffer
mov eax, outbuf ; store passed line buffer
mov lbuf, eax ; store passed line buffer
mov inPtr, 0 ; reset input buffer ptr
mov otPtr, 0 ; reset output buffer ptr
labRD:
mov cloc, fseek(hFile,cloc,0) ; save next file pointer
mov bwrt, fread(hFile,hMem,1024) ; read data from file into buffer
labGO:
mov esi,hMem ; setup input buffer
mov edi,outbuf ; setup output line buffer
starting:
;========================= BUILD A NEW LINE =========================================
rdLine: ; Get Line
mov al,[esi] ; get next input char
inc esi ; incr in pointer
cmp al,13 ; check if CR char
je labCR ; go check for EoR
mov[edi],al ; store next output char
inc edi ; incr out pointer
jmp rdLine ; loop for next
;=======================================================================================
labCR: ; CR found
mov[edi],al ; store CR char
inc edi ; incr out pointer
mov al,[esi]
inc esi
cmp al,10 ; check if LF char
je labLF
labLF: ; LF found
mov[edi],al ; store LF char
inc edi ; incr out pointer
ret
readrec endp
SetConRows PROC USES EBX ESI EDI dwRows:DWORD
;------------------------------------------------------
LOCAL _csbi :CONSOLE_SCREEN_BUFFER_INFO
LOCAL _rcWindow :RECT
LOCAL _rcWork :RECT
;------------------------------------------------------
;get current character rows
INVOKE GetStdHandle,STD_OUTPUT_HANDLE
lea edx,_csbi
INVOKE GetConsoleScreenBufferInfo,eax,edx
movzx ebx,_csbi.srWindow.Bottom
movzx eax,_csbi.srWindow.Top
sub ebx,eax
inc ebx ;EBX = number of character rows in current window
;get console window title bar + border height
;calculate cell height and proposed new client height
INVOKE GetConsoleWindow
xchg eax,edi ;EDI = hWnd
INVOKE GetClientRect,edi,addr _rcWindow
xor eax,eax
mov esi,_rcWindow.top
mov edx,eax
sub esi,_rcWindow.bottom ;ESI = -(client height)
sub eax,esi ;EAX = +(client height)
div ebx ;EAX = character cell height
mul dwRows
xchg eax,ebx ;EBX = proposed new client height
INVOKE GetWindowRect,edi,addr _rcWindow
add esi,_rcWindow.bottom
sub esi,_rcWindow.top ;ESI = title bar + border height
add esi,ebx ;ESI = proposed new window height
;justify new window in desktop work area
INVOKE SystemParametersInfo,SPI_GETWORKAREA,NULL,addr _rcWork,NULL
mov ecx,_rcWindow.top
mov edx,_rcWork.bottom
lea eax,[ecx+esi]
.if eax>edx
xchg eax,edx
sub edx,eax
sub ecx,edx
.if CARRY?
xor ecx,ecx
.endif
.endif
;set window size and position
mov esi,_rcWindow.left
mov edx,_rcWindow.right
sub eax,ecx
sub edx,esi
INVOKE MoveWindow,edi,esi,ecx,edx,eax,TRUE
ret
SetConRows ENDP
SetTextColor proc fore:DWORD,back:DWORD
LOCAL hStdOut:DWORD
invoke GetStdHandle,STD_OUTPUT_HANDLE
mov hStdOut,eax
mov eax,back
shl eax,4
or eax,fore
invoke SetConsoleTextAttribute,hStdOut,eax
ret
SetTextColor endp
END start ; Tell MASM where the program ends
You might shows us the full error message? I guess the problem resist inside gwMacros.inc.
Folks, just to clarify some recent responses:
I don't think the additional macro's file has any bearing on the problem - it is not referenced in this assembly
The full error message is contained in the subject line
I stress the code does not represent a finished product, it is a test harness that I cannot get to assemble
Thanks,
The above code assembles fine after removing "include gwMacros.inc".
it assembles here too
may it be ML / masm32 sdk version issue ?
Quote from: pgw001 on March 25, 2014, 05:20:21 AM
The full error message is contained in the subject line
Perfect. If you could now kindly tell us in which line that error happens, then we might have a chance to find that bug.
Without the macro include, it assembles fine and crashes here with an access violation:
004010FB ³. 8B7D 08 mov edi, [ebp+8]
rdLine ³> 8A06 Úmov al, [esi]
00401100 ³. 46 ³inc esi
Probable reason: testIN.asm is not on my computer, and there is no error check after fopen.
it may be the missing spaces in 2 places
mov[edi],al
mov [edi],al
another possibility is that macros.asm might be better included last
so that all the functions used in the included file are prototyped prior to reference
Folks, many thanks for the suggestions
I have commented out the include statement for gwMacros.inc
I have made the include statement for macros.asm the final include item
I have corrected the mov instruction syntax errors, sadly the assembly still fails as follows:
Error 1 error A2071: initializer magnitude too large for specified size X:\MASM\fileopsr.asm 171 1 Project1
The line no identified (171) points to the - readrec endp statement
Best
Quote from: pgw001 on March 25, 2014, 09:49:19 AM
The line no identified (171) points to the - readrec endp statement
Now it gets mysterious - there is nothing wrong with that line.
On my PC, the attached source works fine with Masm 6.14, 6.15, 9.0, 10.0 and JWasm.
I added an error check after fopen.
I also cannot find anything wrong anywhere in the source after I commented out the include gwMacros.inc statement. What assembler command line are you using?
Last night when I was looking through pgw001's posts I noticed that he uses MS VS as IDE.
My last suggestion is to try assembling the code in pure batch environment i.e. in QEDITOR
Best
Using \Masm32\qeditor.exe could help indeed. I used RichMasm without any problems.
There are several logical errors to fix. Inter alia,
1.
LOCAL cloc :DWORD ; current location variable
is never initialised, and therefore will set the file pointer initially to an arbitrary value ->CRASH.
Test it by commenting out the mov cloc, fseek(hFile,cloc,0)
2. hMem is a local, too, and therefore this will fail in an unpredictable way:
LOCAL hMem :DWORD ; allocated memory handle
...
cmp hMem, 0 ; Check if file open
jne labGO ; Jump if so
You should read The LOCAL variables trap (http://www.webalice.it/jj2006/Masm32_Tips_Tricks_and_Traps.htm) carefully.
broken rdLine: too
- no null checking
- no output buffer size checking
Folks, thanks to all for your perseverance
The observation that I use the Visual Studio 2013 IDE and the recommendation I try qeditor.exe proved to be the guiding lights
The code, including the gwmacros.inc file, assembled and linked without errors or warnings using qeditor - I am not sure
what this says about the VS environment albeit I have now copied the code that made up the 'readrec proc' into a different
test harness which subsequently went on to assemble without error under VS.
Again thanks for your contributions and support - should I advise Microsoft?
Quote from: pgw001 on March 26, 2014, 01:20:37 AMshould I advise Microsoft?
Honestly, Santa Claus doesn't exist, and Microsoft doesn't take advice from its clients ;-)
Quote from: pgw001 on March 26, 2014, 01:20:37 AM
Again thanks for your contributions and support - should I advise Microsoft?
you can try it, but the success will be questionable. So, let it be.
Gunther
QuotelabCR: ; CR found
mov[edi],al ; store CR char
inc edi ; incr out pointer
mov al,[esi]
inc esi
cmp al,10 ; check if LF char
je labLF
labLF: ; LF found
mov[edi],al ; store LF char
inc edi ; incr out pointer
Although the above piece of code will not throw an error, it could mean trouble if the CR character is not followed by an LF character. Your intention should be to skip storing the character if it is NOT an LF but your
code simply continues to process that code you would want to skip! :icon_eek:
Quote from: jj2007 on March 26, 2014, 04:55:19 AM
Honestly, Santa Claus doesn't exist, and Microsoft doesn't take advice from its clients ;-)
They do for the big customers, like the one that requested a Word macro system that can be programmed to silently format your hard drive :biggrin:
Michael,
Quote from: MichaelW on March 27, 2014, 08:35:48 AM
They do for the big customers, like the one that requested a Word macro system that can be programmed to silently format your hard drive :biggrin:
but that's the world of the big money, not the normal users world.
Gunther