For some reason the WriteInt PROC
is not working after I call my fibo PROC
, but it can print the array if I comment the fibo PROC
out. The whole program runs through but never prints the values. Here are the linked libraries I am using: http://kipirvine.com/asm/examples/IrvineExamplesVS2012.zip
I was wondering why it doesn't print to the console? Here is the program I wrote:
INCLUDE Irvine32.inc
printArray PROTO pArray:PTR DWORD, count:DWORD
.data
fiboNum DWORD 1,2,3,4,5,6,7,8,9,10
.code
main PROC
push LENGTHOF fiboNum
push 0
push OFFSET fiboNum
call fibo
Invoke printArray, ADDR fiboNum, LENGTHOF fiboNum
exit
main ENDP
fibo PROC
push ebp
mov ebp, esp
pushad
mov eax, [ebp + 12]
mov ecx, [ebp + 16]
cmp ecx, eax
je leaveNOW
cmp eax, 0 ; Does array need to be setup?
jne calc
push eax
mov eax, [ebp + 8] ; Setup array
mov DWORD PTR [eax], 1
mov DWORD PTR [eax + 4], 1
add ecx, 2
pop eax
calc:
mov ebx, [ebp + 8]
mov edx, [ebx]
add edx, [ebx + 4]
mov [ebx + 8], edx
lea ebx, [ebx + 4]
inc eax
push ecx
push eax
push ebx
call fibo
leaveNow:
popad
pop ebp
ret 12
fibo ENDP
printArray PROC USES ecx edx eax,
pArray:PTR DWORD,
count:DWORD
mov ecx, count
mov edx, pArray
L1:
mov eax, [edx]
call WriteInt
call CrLf
add edx, 4
loop L1
ret
printArray ENDP
END main
WriteInt PROC
in Irvines linked libraries:
;-----------------------------------------------------
WriteInt PROC
;
; Writes a 32-bit signed binary integer to the console window
; in ASCII decimal.
; Receives: EAX = the integer
; Returns: nothing
; Comments: Displays a leading sign, no leading zeros.
; Last update: 7/11/01
;-----------------------------------------------------
WI_Bufsize = 12
true = 1
false = 0
.data
buffer_B BYTE WI_Bufsize DUP(0),0 ; buffer to hold digits
neg_flag BYTE ?
.code
pushad
CheckInit
mov neg_flag,false ; assume neg_flag is false
or eax,eax ; is AX positive?
jns WIS1 ; yes: jump to B1
neg eax ; no: make it positive
mov neg_flag,true ; set neg_flag to true
WIS1:
mov ecx,0 ; digit count = 0
mov edi,OFFSET buffer_B
add edi,(WI_Bufsize-1)
mov ebx,10 ; will divide by 10
WIS2:
mov edx,0 ; set dividend to 0
div ebx ; divide AX by 10
or dl,30h ; convert remainder to ASCII
dec edi ; reverse through the buffer
mov [edi],dl ; store ASCII digit
inc ecx ; increment digit count
or eax,eax ; quotient > 0?
jnz WIS2 ; yes: divide again
; Insert the sign.
dec edi ; back up in the buffer
inc ecx ; increment counter
mov BYTE PTR [edi],'+' ; insert plus sign
cmp neg_flag,false ; was the number positive?
jz WIS3 ; yes
mov BYTE PTR [edi],'-' ; no: insert negative sign
WIS3: ; Display the number
mov edx,edi
call WriteString
popad
ret
WriteInt ENDP
EDIT:
Okay, so I kinda of fixed it but I don't know why (specifically). Apparently the CheckInit macro was not initializing the console handles when I was calling the WriteInt Proc from inside one of the procs of my program. So, I just called the WriteInt as the first instruction in my program, and it set up the console handles correctly. Not sure why it didn't initialize the console handles when it was in my proc. Anyone have any ideas on why it would do that?
Here is the CheckInIt macro:
;-------------------------------------------------------------
CheckInit MACRO
;
; Helper macro
; Check to see if the console handles have been initialized
; If not, initialize them now.
;-------------------------------------------------------------
LOCAL exit
cmp InitFlag,0
jne exit
call Initialize
exit:
ENDM
This is the mistake:
add ecx, 2
pop eax
ECX
is the defined length of fiboNum
passed on the stack (EBP+16
) and the break condition for fibo
. If you increment it, you give fibo
the chance to write behind fiboNum
and to overwrite other data - in this case Irvine's InitFlag
. Therefore CheckInit
thinks that the STDOUT handle is already saved and continues without saving it. The following WriteConsole
gets a wrong handle, doesn't write and signales an error with EAX=0. GetLastError
gives the error code 6 (ERROR_INVALID_HANDLE).
The count of already written numbers is passed as second argument on the stack (ebp + 12
) and hold in EAX
in fibo
. It's obvious to increment it after storing two numbers in fiboNum
. So change the snippet above to
pop eax
add eax, 2
Consider, that fiboNum
must contain at least 3 elements.