MASM中WriteConsole返回false求助:数组值打印失败
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
lpBufferParameter
You're pushing the value of the array element (ebxholds[dArray + eax*4], e.g., 10, 11) instead of a pointer to a character buffer containing the string representation of that integer.WriteConsoleexpects 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
WriteConsoleoutputs 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 checkscmp eax,11which 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
tempBufferto 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
GetStdHandlecall outside the loop (no need to retrieve it every iteration). - Added a newline print to make output more readable.
- Corrected the
lpBufferparameter 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

