为什么WriteConsoleOutputAttribute无法修改字符颜色,nb始终为0,这是一个填充控制台的程序,用的是汇编语言

include Irvine32.inc
.data
use byte ?,0
outi HANDLE 0
consoleInfo CONSOLE_SCREEN_BUFFER_INFO <>
STD_OUTPUT_HANDLE = -11
attribute label word
val1 byte 0
val2 byte 0
xy COORD <0,0>
nb dword 0
ll dword 1
.code
main proc
invoke Getstdhandle, STD_OUTPUT_HANDLE
MOV outi,eax
invoke GetConsoleScreenBufferInfo,outi,addr consoleInfo
mov ax,consoleInfo.dwSize.X
add ax,consoleInfo.srWindow.Right
mov xy.X,ax
mov ax,consoleInfo.dwSize.Y
add ax,consoleInfo.srWindow.Top
mov xy.Y,ax
mov dx,ax
movzx ecx,consoleInfo.srWindow.Right
movzx eax,consoleInfo.srWindow.Left
sub ecx,eax
L3:
push ecx
movzx ecx,consoleInfo.srWindow.Top
movzx eax,consoleInfo.srWindow.Bottom
sub ecx,eax
call Randomize
L1:
mov eax,0FFh
call RandomRange
inc eax
call WriteChar
mov eax,16d
call RandomRange
mov val1,al
shr al,1
jc L2
mov val1,4
L2:
push ecx
push edx
PUSH xy.X
dec xy.X
invoke WriteConsoleOutputAttribute, outi, addr attribute, ll, xy, addr nb
pop xy.X
pop edx
pop ecx
inc xy.X
loop L1
pop ecx
mov xy.X,ax
inc xy.Y
dec ecx
jne L3
exit
main endp
end main
...全文
316 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
我知道手工把code=text改成code=asm是可以的,只是懒得修改。
这里总共也没几个人,大熊猫侯佩都一两个月不露一次面,老赵可以来增加一些人气~
赵4老师 2021-01-28
  • 打赏
  • 举报
回复
楼上添加asm语法高亮后:

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

.data
outi dword 0
consoleInfo CONSOLE_SCREEN_BUFFER_INFO<>
STD_OUTPUT_HANDLE = -11
attribute dd 0
xy COORD <0, 0>
ll dword 1
nb dword 0

.code
main:
  invoke GetStdHandle, STD_OUTPUT_HANDLE
  MOV outi,eax 

  invoke GetConsoleScreenBufferInfo,outi,addr consoleInfo
  movzx eax, consoleInfo.srWindow.Right
  movzx ecx, consoleInfo.srWindow.Bottom
  movzx edx, consoleInfo.srWindow.Left
  movzx ebx, consoleInfo.srWindow.Top
  inc eax
  inc ecx
  sub eax, edx
  sub ecx, ebx
  mul ecx
  mov ll, eax
  mov xy.x, dx
  mov xy.y, bx
  mov ecx, eax
  shl eax, 1
  push ebp
  mov ebp, esp
  sub esp, eax
  mov edi, esp
  mov attribute, edi
  cld
  mov ax, FOREGROUND_GREEN or FOREGROUND_RED or FOREGROUND_INTENSITY or BACKGROUND_BLUE
  rep stosw
  invoke WriteConsoleOutputAttribute, outi, attribute, ll, dword ptr xy, addr nb 

  leave
  invoke ExitProcess, 0

end main
  • 打赏
  • 举报
回复
改写一个简单的例子:

.686
.model flat, stdcall
option casemap: none

include d:\masm32\include\windows.inc
include d:\masm32\include\kernel32.inc
include d:\masm32\include\user32.inc
includelib d:\masm32\lib\kernel32.lib
includelib d:\masm32\lib\user32.lib

.data
outi dword 0
consoleInfo CONSOLE_SCREEN_BUFFER_INFO<>
STD_OUTPUT_HANDLE = -11
attribute dd 0
xy COORD <0, 0>
ll dword 1
nb dword 0

.code
main:
invoke GetStdHandle, STD_OUTPUT_HANDLE
MOV outi,eax

invoke GetConsoleScreenBufferInfo,outi,addr consoleInfo
movzx eax, consoleInfo.srWindow.Right
movzx ecx, consoleInfo.srWindow.Bottom
movzx edx, consoleInfo.srWindow.Left
movzx ebx, consoleInfo.srWindow.Top
inc eax
inc ecx
sub eax, edx
sub ecx, ebx
mul ecx
mov ll, eax
mov xy.x, dx
mov xy.y, bx
mov ecx, eax
shl eax, 1
push ebp
mov ebp, esp
sub esp, eax
mov edi, esp
mov attribute, edi
cld
mov ax, FOREGROUND_GREEN or FOREGROUND_RED or FOREGROUND_INTENSITY or BACKGROUND_BLUE
rep stosw
invoke WriteConsoleOutputAttribute, outi, attribute, ll, dword ptr xy, addr nb

leave
invoke ExitProcess, 0

end main

zara 2021-01-26
  • 打赏
  • 举报
回复
写的位置不对吧,没在屏幕上,甚至没在 buffer 里。
另外,ecx 可能会被子程函数改变的,所以你这里使用上是问题,要么换个如 esi 或 edi 或 ebx 要么在子程前保持它然后再恢复。开始那里计算两重循环的应该也不对,看出来的结果就不合理。
还是上调试器吧,简单如 OllyDbg,在有问题的地方断点,看看现场的内容,大致就有些错误的线索了。

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧