News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Question on some code...

Started by Spudster, December 20, 2008, 11:37:22 AM

Previous topic - Next topic

Spudster

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?

Neil

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.

jj2007

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

UncleHenry

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.

MichaelW

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

eschew obfuscation