I created this code last night (when I should have been sleeping), and it works fine. It doesn't do a lot, but I'm proud of it. I just wanted your input on anything that I might be able to improve. Whether it be my syntax, or if there are better ways to work with the API, or the way I use variables. Whatever it is, I'm interested to hear it. I'm not real quick at learning this stuff, but I enjoy it. Thanks to everyone that's been helping me here. No way I could have figured this out on my own. I do have a question. Why on GetConsoleScreenBufferInfo do I use ADDR and on SetConsoleCursorPosition I use DWORD PTR []? Honestly I don't even know what the latter is doing. I think it was something I found on the forum here.
.586
.model flat, stdcall
option casemap:none
include windows.inc
include masm32.inc
include kernel32.inc
include user32.inc
include gdi32.inc
includelib masm32.lib
includelib kernel32.lib
includelib user32.lib
includelib gdi32.lib
.const
consTitle db "First Console Program!",0
.data
str1 db "This is text.",0
.data?
hConsole HANDLE ?
hConsoleOutput HANDLE ?
cCoord COORD <?,?>
hConsCursPos HANDLE ?
hBuffInfo HANDLE ?
.code
main:
push eax
push ebx
push ecx
push edx
call num_call
pop edx
pop ecx
pop ebx
pop eax
invoke ExitProcess,0
num_call proc
LOCAL spBuffInfo:CONSOLE_SCREEN_BUFFER_INFO
invoke SetConsoleTitle,addr consTitle
invoke GetStdHandle,STD_OUTPUT_HANDLE
mov hConsole,eax
invoke GetConsoleScreenBufferInfo,hConsole,ADDR spBuffInfo
mov hBuffInfo,eax
mov dx,spBuffInfo.dwCursorPosition.y
add dx,3
mov cCoord.y,dx
mov cCoord.x,3
invoke SetConsoleCursorPosition,hConsole,DWORD PTR [cCoord]
invoke WriteConsole,hConsole,addr str1,13,0,0
ret
num_call endp
end main
I read on a page talking about optimization that you want to keep from jumping around in your code as much as possible, but there is no way I want to type this out every time. I haven't learned much about them, but I assume that I could use this to create my own macros that I could use whenever I need?
Spudster,
There is a much easier way of positioning the cursor by use of the loc macro :-
loc 10,3
This places the cursor at column 10 on row 3. I know that you want to know the ins & outs of ways of doing things, but from my point of view you don't have to know how the engine works to drive a car & it leaves you more time to actually write a program. To coin a phrase "it stops you from reinventing the wheel" :green.
Anyway that's my opinion others on this forum might think differently.
Quote from: Spudster on December 20, 2008, 11:37:22 AM
Why on GetConsoleScreenBufferInfo do I use ADDR and on SetConsoleCursorPosition I use DWORD PTR []?
invoke SetConsoleCursorPosition,hConsole,DWORD PTR [cCoord] tells the assembler "push the dword that is at the address of cCoord". You might as well use the shorter
invoke SetConsoleCursorPosition, hConsole, cCoord
Most of the time we pass DWORDs to a procedure, but Masm allows also to pass structures such as COORD directly. Below is an example working with RECT, a 4*DWORD structure.
include \masm32\include\masm32rt.inc ; a shortcut for the includes, libraries and macros
RecTest PROTO:RECT
.code
AppName db "Masm32:", 0
rc RECT <12345678, 98765432, 1234, 4321> ; left, top, right, bottom
start: invoke RecTest, rc
getkey
exit
RecTest proc rc1:RECT
print chr$("left", 9)
print str$(rc1.left), 13, 10
print chr$("top", 9)
print str$(rc1.top), 13, 10
print chr$("right", 9)
print str$(rc1.right), 13, 10
print chr$("bottom", 9)
print str$(rc1.bottom), 13, 10
ret
RecTest endp
end start
Quote from: Spudster on December 20, 2008, 11:37:22 AM
Why on GetConsoleScreenBufferInfo do I use ADDR and on SetConsoleCursorPosition I use DWORD PTR []?
See also the MSDN docs: the 2nd param of GetConsoleScreenBufferInfo is of type PCONSOLE_SCREEN_BUFFER_INFO. The initial "P" (and the initial "lp" in the param name) tells you this is pointer, i. e. an address, so on the stack you must push the address of a CONSOLE_SCREEN_BUFFER_INFO structure. OTOH SetConsoleCursorPosition takes a COORD, which is defined as a 4 byte structure, so the actual 4 byte value must be pushed on the stack, not the address of the piece of memory where you stored them.
And to extend the information a little further, Invoke can also correctly handle 8-byte data items.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
;COORD STRUCT
; x WORD ?
; y WORD ?
;COORD ENDS
;POINT STRUCT
; x DWORD ?
; y DWORD ?
;POINT ENDS
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
dword1 dd 1
qword1 dq 2
coord COORD <3,4>
point POINT <5,6>
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
target proc dwordArg:DWORD, qwordArg:QWORD, coordArg:COORD, pointArg:POINT
;-------------------------------------------------------------
; The MASM32 str$ macro converts a dword to a decimal string.
;-------------------------------------------------------------
print str$(dwordArg)
;--------------------------------------------------------------------
; Display the qword (64-bit) parameter with the CRT printf function.
;--------------------------------------------------------------------
invoke crt_printf, chr$("%I64d"), qwordArg
;---------------------------------------------------------------------
; Zero extend the word members to dwords so they will work with str$.
;---------------------------------------------------------------------
movzx eax, coordArg.x
print str$(eax)
movzx eax, coordArg.y
print str$(eax)
print str$(pointArg.x)
print str$(pointArg.y),13,10
ret
target endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke target, dword1, qword1, coord, point
push point.y
push point.x
push coord
;-------------------------------------------------------
; MASM requires the DWORD PTR below because the access
; size (32 bits) does not match defined size (64 bits).
;-------------------------------------------------------
push DWORD PTR qword1+4
push DWORD PTR qword1
push dword1
call target
inkey "Press any key to exit..."
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start