You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MASM中WriteConsole返回false求助:数组值打印失败

Fixing WriteConsole Failure in Your MASM Array Printing Code

Let's break down why your WriteConsole call is returning false (eax=0) and fix the issues step by step:

Key Issues in Your Code

  • Incorrect lpBuffer Parameter
    You're pushing the value of the array element (ebx holds [dArray + eax*4], e.g., 10, 11) instead of a pointer to a character buffer containing the string representation of that integer. WriteConsole expects a pointer to memory where the characters to print are stored—passing a raw integer value here will cause it to try reading from an invalid memory address, leading to a failed call.

  • Mismatched Data Type for Output
    WriteConsole outputs ASCII/Unicode characters, not raw binary integers. Even if you fixed the pointer issue, passing an int value directly won't print the number you expect (it would print the ASCII character corresponding to that integer, e.g., 10 is a newline character). You need to convert your integer values to their string equivalents first.

  • Out-of-Bounds Array Access
    Your array has 10 elements (dArray dd 10 dup (?)), but your loop checks cmp eax,11 which will run 11 times (from 0 to 10), accessing memory beyond the end of your array.

Corrected Code

Here's the fixed version with embedded explanations:

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\msvcrt.lib

.data
dArray dd 10 dup (?)          ; 10-element integer array
CharsWritten dd ?             ; For WriteConsole's output count
LoopCounter dd 0
StdHandle dd ?
tempBuffer db 10 dup (0)      ; Buffer to hold string version of integer
CRLF db 0Dh,0Ah               ; Carriage return + newline for readability

.code
PrintArrayToScreen proc
    ; Get standard output handle once, not every loop iteration
    mov eax, STD_OUTPUT_HANDLE
    push eax
    call GetStdHandle
    mov StdHandle, eax

innerPrintLoop:
    mov eax, [LoopCounter]
    cmp eax, 10               ; Stop after 10 elements (0-9)
    jge endPrintLoop          ; Exit loop if we've processed all elements

    ; Get the integer value from the array
    mov ecx, offset dArray
    mov ebx, [ecx + eax * 4]

    ; Convert integer to string using masm32's dwtoa function
    push ebx
    push offset tempBuffer
    call dwtoa                ; tempBuffer now holds the string of the integer

    ; Call WriteConsole with the correct parameters
    push 0                    ; lpReserved (NULL)
    push offset CharsWritten  ; Pointer to CharsWritten
    push eax                  ; eax holds length of the string returned by dwtoa
    push offset tempBuffer    ; Pointer to our string buffer
    push StdHandle            ; Output handle
    call WriteConsole

    ; Print a newline after each number for readability
    push 0
    push offset CharsWritten
    push 2
    push offset CRLF
    push StdHandle
    call WriteConsole

    ; Increment loop counter
    inc eax
    mov LoopCounter, eax
    jmp innerPrintLoop

endPrintLoop:
    ret
PrintArrayToScreen endp

arrayLoop proc
    mov eax, offset dArray
    mov bx, 10
    mov ecx, 0
innerLoop:
    mov [eax + ecx * 4], bx
    inc bx
    add ecx, 1
    cmp ecx, 10
    jne innerLoop
    ret
arrayLoop endp

start:
    call arrayLoop
    call PrintArrayToScreen
    push 0
    call ExitProcess
end start

What Changed?

  • Added a tempBuffer to store the string representation of each integer.
  • Used dwtoa (a MASM32 library function) to convert integers to ASCII strings—this handles formatting work for you.
  • Fixed the loop condition to stop after 10 elements instead of 11.
  • Moved the GetStdHandle call outside the loop (no need to retrieve it every iteration).
  • Added a newline print to make output more readable.
  • Corrected the lpBuffer parameter to pass a pointer to the string buffer instead of the raw integer value.

How to Verify

After assembling and linking, running the program should print numbers 10 through 19 each on a new line. You could also call GetLastError immediately after your original failed WriteConsole call to confirm the root cause—before fixing, it would likely return ERROR_INVALID_ADDRESS (0x6E) due to the invalid pointer passed in lpBuffer.

内容的提问来源于stack exchange,提问作者Mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 12:18:13