Assembly 如何在MASM中获取当前光标位置

Assembly 如何在MASM中获取当前光标位置,assembly,masm,irvine32,Assembly,Masm,Irvine32,我正在写一个IQ测试生成程序,其中我必须随机生成包括口头和非口头问题的问题。为了生成非语言问题,我想显示字母和字母将以圆形或三角形显示的问题 但我不知道如何定位它们。例如,在一个非语言问题中,我想通过编写以下代码将字母和数字定位为三角形: mov al, alpha call writechar add dl, 4 call gotoxy mov al, num call writedec sub dl, 2 add dh, 1 call gotoxy mov al, alpha call

我正在写一个IQ测试生成程序,其中我必须随机生成包括口头和非口头问题的问题。为了生成非语言问题,我想显示字母和字母将以圆形或三角形显示的问题

但我不知道如何定位它们。例如,在一个非语言问题中,我想通过编写以下代码将字母和数字定位为三角形:

mov al, alpha 
call writechar
add dl, 4
call gotoxy
mov al, num
call writedec 
sub dl, 2
add dh, 1
call gotoxy
mov al, alpha 
call writechar
这是我已经知道的

dh=行

dl=列

打电话给gotoxy

Gotoxy将光标定位在控制台的起始位置,而不是当前位置。这就是我遇到的问题


我假设应该有一种获取当前光标位置的方法,这样我就可以在生成系列形状时,通过添加和减去当前值dhdl来前后定位光标。

您可以在线获得Irvine32帮助:。为获取光标位置指定了WinAPI函数:。不幸的是,结构
控制台屏幕缓冲区信息
的描述不正确。相应坐标结构的名称为
dwCursorPosition

下面是一个如何使用它的示例:

INCLUDE Irvine32.inc
INCLUDELIB Irvine32.lib

.DATA
    txt1 db "Current Cursor Position is X=",0
    txt2 db " Y=",0
    BufferInfo CONSOLE_SCREEN_BUFFER_INFO <>

.CODE
main PROC

    lea edx, txt1
    call WriteString

    invoke GetStdHandle, STD_OUTPUT_HANDLE
    invoke GetConsoleScreenBufferInfo, eax, ADDR BufferInfo

    movzx eax, BufferInfo.dwCursorPosition.X
    call WriteInt

    lea edx, txt2
    call WriteString
    movzx eax, BufferInfo.dwCursorPosition.Y
    call WriteInt

    exit

main ENDP

END main
包括Irvine32.inc
INCLUDELIB Irvine32.lib
.数据
txt1 db“当前光标位置为X=”,0
txt2 db“Y=”,0
缓冲区信息控制台\屏幕\缓冲区\信息
.代码
主进程
lea edx,txt1
通话记录
调用GetStdHandle、STD\u输出\u句柄
调用GetConsoleScreenBufferInfo、eax、ADDR BufferInfo
movzx eax,BufferInfo.dwCursorPosition.X
呼叫写入
lea edx,txt2
通话记录
movzx eax,BufferInfo.dwCursorPosition.Y
呼叫写入
出口
主端
端干管

您可以在线获得Irvine32帮助:。为获取光标位置指定了WinAPI函数:。不幸的是,结构
控制台屏幕缓冲区信息
的描述不正确。相应坐标结构的名称为
dwCursorPosition

下面是一个如何使用它的示例:

INCLUDE Irvine32.inc
INCLUDELIB Irvine32.lib

.DATA
    txt1 db "Current Cursor Position is X=",0
    txt2 db " Y=",0
    BufferInfo CONSOLE_SCREEN_BUFFER_INFO <>

.CODE
main PROC

    lea edx, txt1
    call WriteString

    invoke GetStdHandle, STD_OUTPUT_HANDLE
    invoke GetConsoleScreenBufferInfo, eax, ADDR BufferInfo

    movzx eax, BufferInfo.dwCursorPosition.X
    call WriteInt

    lea edx, txt2
    call WriteString
    movzx eax, BufferInfo.dwCursorPosition.Y
    call WriteInt

    exit

main ENDP

END main
包括Irvine32.inc
INCLUDELIB Irvine32.lib
.数据
txt1 db“当前光标位置为X=”,0
txt2 db“Y=”,0
缓冲区信息控制台\屏幕\缓冲区\信息
.代码
主进程
lea edx,txt1
通话记录
调用GetStdHandle、STD\u输出\u句柄
调用GetConsoleScreenBufferInfo、eax、ADDR BufferInfo
movzx eax,BufferInfo.dwCursorPosition.X
呼叫写入
lea edx,txt2
通话记录
movzx eax,BufferInfo.dwCursorPosition.Y
呼叫写入
出口
主端
端干管

没有人人都知道的
gotoxy
通用汇编函数,因此您必须使用某种支持库,其中包含此类函数。检查您使用的是哪种库,以及它的文档(或者它的源代码,如果源代码可用)。也许这是欧文图书馆?32位windows变体?那你可以试试。。。Irvine库中没有读取光标位置的函数,您可以使用底层的windows API调用,也可以通过重新设计代码的逻辑来完全避免这种需要。如果是Irvine 32库,则使用
gotoxy
(以及其他调用,如
writedec
writechar
)不会修改
dx
寄存器中的值,因此您可以一直在类似的代码中调整
dh/dl
,它将保留其值。所有Irvine lib调用保留所有寄存器值,但返回函数值的输出寄存器除外。但是
writechar
本身可能会将内部控制台光标移动1个字符,因此下一个
writechar
不会覆盖上一个(
dx
不受
调用write***
的影响)。=不清楚,你在问什么/什么不起作用如果这是关于初始位置,那么设计屏幕,它应该看起来如何。。。你在为每个问题重新绘制整个屏幕吗?然后,您可以准确地设计最初要从何处开始绘图,您不需要读取旧的光标位置,只需根据需要重新绘制屏幕,并将所有内容放置在计划的位置。(寻找某种“清晰屏幕”。.我从未使用过Irvine32,所以我不确定控制台是如何工作的)继续试验一段时间)是的,我正在使用Irvine32库。你确定它不是16位DOS变体吗?从您发布的代码来看,这并不明显,因为您只使用了8位和16位寄存器,因此这类代码在两个目标平台中看起来都是一样的,但这对于理解控制台行为可能至关重要,因为windows“控制台”是模拟的(比如它可以调整到一些奇怪的大小,如174x33),虽然DOS有图形卡支持的HW文本模式(具有固定大小等)。没有人人都知道的
gotoxy
通用汇编函数,因此您必须使用某种支持库,其中包含此类函数。检查您使用的是哪种库,以及它的文档(或者它的源代码,如果源代码可用)。也许这是欧文图书馆?32位windows变体?那你可以试试。。。Irvine库中没有读取光标位置的函数,您可以使用底层的windows API调用,也可以通过重新设计代码的逻辑来完全避免这种需要。如果是Irvine 32库,则使用
gotoxy
(以及其他调用,如
writedec
writechar
)不会修改
dx
寄存器中的值,因此您可以一直在类似的代码中调整
dh/dl
,它将保留其值。所有Irvine lib调用保留所有寄存器值,但返回函数值的输出寄存器除外。但是
writechar
本身可能会将内部控制台光标移动1个字符,因此下一个
writechar
不会覆盖上一个
dx
不会受到
调用的影响