I have some simple code that gets the console attributes then changes the text color. Something simple is printed to the console and then I try to put back the text colors. I'm missing something because I can not put back the console colors the way they were. Can someone help because I'm confused on what's wrong. Do I need to be debugging differently or is there another way to debug?
.686
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
.const
ccBlack EQU 0
ccDarkBlue EQU 1
ccDarkGreen EQU 2
ccSoftBlue EQU 3
ccDarkRed EQU 4
ccDarkPurple EQU 5
ccTan EQU 6
ccLightGrey EQU 7
ccGrey EQU 8
ccBrightBlue EQU (1 or ccGrey)
ccBrightGreen EQU (2 or ccGrey)
ccBabyBlue EQU (3 or ccGrey)
ccBrightRed EQU (4 or ccGrey)
ccBrightPurple EQU (5 or ccGrey)
ccYellow EQU (6 or ccGrey)
ccWhite EQU (7 or ccGrey)
.data
hStdOut HANDLE 0
szHello db "hello", 13, 10, 0
szError db "error", 13, 10, 0
csbi CONSOLE_SCREEN_BUFFER_INFO <>
.code
start:
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov hStdOut, eax
mov csbi.wAttributes, 0
invoke GetConsoleScreenBufferInfo, hStdOut, addr csbi
cmp eax, 0
jnz @continueNoFail
invoke SetConsoleTextAttribute, hStdOut, ccBrightRed
invoke WriteFile, hStdOut, addr szError, 7, NULL, NULL
invoke SetConsoleTextAttribute, hStdOut, ccLightGrey
jmp @endend
@continueNoFail:
invoke SetConsoleTextAttribute, hStdOut, ccBrightPurple
invoke WriteFile, hStdOut, addr szHello, 7, NULL, NULL
;this line is supposed to set the console back to the orig colors
invoke SetConsoleTextAttribute, hStdOut, csbi.wAttributes
cmp eax, 0
jnz @endend
invoke SetConsoleTextAttribute, hStdOut, ccBrightRed
invoke WriteFile, hStdOut, addr szError, 7, NULL, NULL
invoke SetConsoleTextAttribute, hStdOut, ccLightGrey
jmp @endend
@endend:
xor eax, eax
invoke ExitProcess, eax
end start
Quote from: thomas_remkus on February 22, 2008, 02:06:38 AM
invoke SetConsoleTextAttribute, hStdOut, csbi.wAttributes
use movzx and push register, masm has bugs with zero extending unsigned word/byte arguments
First off -- thanks for a quick response!!!
Seriously?? MASM has a bug with "zero extending unsigned word/byte arguments"?? Can you explain what that mean?
Is there a version of ML that has this bug fixed? I have commercial licenses of Visual Studio up to 2005 and have 2008 installed as well.
Is there a list of bugs for MASM so I might try and avoid this later?
The invoke is being encoded as:
00401098 6A00 push 0
0040109A 66FF351C304000 push word ptr [40301Ch]
004010A1 FF3500304000 push dword ptr [403000h]
004010A7 E858010000 call fn_00401204
Pushing a DWORD and then a WORD, and messing up the stack alignment.
It should have been encoded as:
00401082 66680000 push 0
00401086 66FF351C304000 push word ptr [40301Ch]
0040108D FF3500304000 push dword ptr [403000h]
00401093 E85C010000 call fn_004011F4
Pushing a WORD and a WORD, and maintaining the DWORD stack alignment.
The workaround is easy:
movzx eax, csbi.wAttributes
invoke SetConsoleTextAttribute, hStdOut, eax
Ah "MichaelW", someone who really knows their stuff. Awesome! Are there a list of other issues like this that I can d/l so I am more aware of the issues? Should I just avoid "invoke" and ".if" and such macros because of issues?
This has driven me crazy today and I would have never thought of the stack being confused.
i was about to post disassembly... but Michael was faster :wink
As far as i know this bug is present in all ML versions v6.14--v9.0, and i doubt it will ever be fixed ( i'm aware of a few more bugs but too tired to write more right now).
I can't recall having problems with this particular bug with anything other than the SetConsoleTextAttribute function, and it has been so long that it took me a while to recall the experience. Everything has bugs, it's just a matter of learning how to avoid them.
OK. I have now looked up the [movzx] and understand this issue more. The disasm is over my head but I'll pull this up in OllyDbg and see what I might be able to see by coding with the "invoke" and then with the "push/call".
If you get a little pep and want to let me know what the bug list is I would really appreciate it. I'm surprised there's not a list already maintained somewhere. If there is ... please shoot me a link!
Does that mean that there might be an issue with the proto for just this function? I can't tell you how pleased I am to get past this tonight.
The prototype is:
SetConsoleTextAttribute PROTO :DWORD,:DWORD
The problem is with invoke's handling of WORD parameters. There is an even easier workaround:
invoke SetConsoleTextAttribute, hStdOut, DWORD PTR csbi.wAttributes
Quote from: drizz on February 22, 2008, 02:51:41 AMtoo tired to write more right now
Here are some links. In most threads you can find my posts.
http://www.masm32.com/board/index.php?topic=7983.0
http://www.masm32.com/board/index.php?topic=1026.0
http://www.masm32.com/board/index.php?topic=7866.msg57776#msg57776
http://www.asmcommunity.net/board/index.php?topic=25665.0
http://www.asmcommunity.net/board/index.php?topic=22227.0
http://www.asmcommunity.net/board/index.php?topic=19445.0
Hello,
When you have this sort of problems,translating a word to a dword,use
Quote
movzx edx,csbi.wAttributes
invoke SetConsoleTextAttribute, hStdOut,edx
and .... it work at each time
You have a bug
Quote
invoke WriteFile, hStdOut, addr szError, 7, addr NumberOfBytesWritten, NULL
Winhelp:
lpNumberOfBytesWritten
Points to the number of bytes written by this function call. WriteFile sets this value to zero before doing any work or error checking.
If lpOverlapped is NULL, lpNumberOfBytesWritten cannot be NULL.