【问题标题】:Irvine WriteInt not printing尔湾 WriteInt 不打印
【发布时间】:2013-11-30 03:30:29
【问题描述】:

由于某种原因,在我调用我的fibo PROC 后,WriteInt PROC 无法正常工作,但如果我将fibo PROC 注释掉,它可以打印数组。整个程序运行,但从不打印值。以下是我正在使用的链接库:http://kipirvine.com/asm/examples/IrvineExamplesVS2012.zip

我想知道为什么它不打印到控制台?这是我写的程序:

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 在欧文链接库中:

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

编辑:

好的,所以我修复了它,但我不知道为什么(特别是)。显然,当我从程序的一个过程中调用 WriteInt Proc 时,CheckInit 宏没有初始化控制台句柄。因此,我只是将 WriteInt 作为程序中的第一条指令调用,它正确设置了控制台句柄。不知道为什么它在我的过程中没有初始化控制台句柄。有人对它为什么会这样做有任何想法吗?

这里是 CheckInIt 宏:

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

【问题讨论】:

  • 可能是因为 CheckInit 没有继续执行 WriteInt 就返回了?

标签: assembly x86 masm irvine32


【解决方案1】:

这是错误:

add ecx, 2
pop eax

ECX 是在堆栈上传递的 fiboNum 的定义长度 (EBP+16) 和 fibo 的中断条件。如果你增加它,你让fibo 有机会写在fiboNum 后面并覆盖其他数据——在这种情况下是欧文的InitFlag。因此CheckInit 认为 STDOUT 句柄已经保存并继续而不保存它。下面的WriteConsole 得到了错误的句柄,没有写入并用 EAX=0 发出错误信号。 GetLastError 给出错误代码 6 (ERROR_INVALID_HANDLE)。

已写入数字的计数作为堆栈上的第二个参数 (ebp + 12) 传递,并保存在 EAX 中的 fibo 中。在fiboNum 中存储两个数字后,很明显要增加它。所以把上面的sn-p改成

pop eax
add eax, 2

请考虑,fiboNum 必须至少包含 3 个元素。

【讨论】:

    猜你喜欢
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    相关资源
    最近更新 更多