Masm32:SetConsoleTextAttribute

Masm32: SetConsoleTextAttribute

我是汇编新手。我需要使用 Masm32 循环更改文本颜色(5 次 - 5 种不同的颜色)。我的代码:

Main PROC
    LOCAL hStdout:DWORD
    call SetConsoleTitleA
    push -11
    call GetStdHandle
    mov hStdout,EAX

    mov BX,5
        lp:

        push hStdout
        push 2
        call SetConsoleTextAttribute

        push 0
        push 0
        push 24d
        push offset sWriteText
        push hStdout
        call WriteConsoleA

        dec BX
    jnz lp

    push 2000d
    call Sleep

    push 0
    call ExitProcess

    Main ENDP
end Main

P.S。对不起我的英语。

问题 1

正如 Raymond Chen 所暗示的那样,对 SetConsoleTitle 的调用是不正确的。

Main PROC
    LOCAL hStdout:DWORD
    call SetConsoleTitleA

请注意,您没有将任何参数压入 SetConsoleTitle 的堆栈。这意味着在此调用之后堆栈已损坏。

一旦这个问题得到解决,我们就可以继续解决问题 2。

问题#2

根据__stdcall calling convention arguments are pushed right-to-left. But in the code the arguments are being pushed left-to-right. In the code above this is the call sequence for SetConsoleTextAttribute

push hStdout
push 2
call SetConsoleTextAttribute

给定函数的签名:

BOOL WINAPI SetConsoleTextAttribute(
  _In_ HANDLE hConsoleOutput,
  _In_ WORD   wAttributes
);

代码像下面的 C 代码一样调用这个函数,

SetConsoleTextAttribute(2, hStdout);

这是相反的。调用应该是:

push 2
push hStdout
call SetConsoleTextAttribute

问题 3

代码忽略所有 return 值,GetStdHandle 除外。对于 SetConsoleTextAttribute,如果函数成功,return 值为非零值。如果函数 return 为零,则函数调用失败,并且 对于此函数 1 扩展错误信息可通过调用 GetLastError。 MSDN 上的文档包含有关每个其他函数的信息以及它们如何指示错误。


1并非所有函数在失败时都会调用 SetLastError。不这样想会导致很多问题。还要注意的是,设置错误的函数只有在出现错误时才会这样做。

另外值得一读的是 The History Of Calling Conventions The Old New Thing 系列。