Search code examples
assemblyx86masmirvine32

Irvine WriteInt not printing


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

Solution

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