Where to get a simple program exemple for leading with console input-output ?
http://www.google.de/search?hl=de&q=assembler+console+input+output+windows+api&meta=
There should be something for you.
Quote from: mnemonic on March 18, 2005, 04:33:08 PM
http://www.google.de/search?hl=de&q=assembler+console+input+output+windows+api&meta=
There should be something for you.
I dont like Basic but may be it serves me !
Thank you so much indeed !
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
.data
msg1 db 'Please type your name',13,10,0
msg2 db 'Nice to see you ',0
.data?
buffer db 100 dup(?)
.code
start:
invoke StdOut,ADDR msg1
invoke StdIn,ADDR buffer,100 ; receive text input
invoke StdOut,ADDR msg2
invoke StdOut,ADDR buffer
invoke ExitProcess,0
END start
Hi all and Vortex
Thank you for your help. I go to study this case
Regards
From the example mentioned above you may want to have a buffer with length of 100+1 initialized to 0 if you want to print it with StdOut() instead.
StdIn() uses ReadFile() which handles the buffer as binary (so it's not padding it with a null terminating 0) and as StdOut() uses StrLen() it may have trouble to return the real length of the buffer if it's directly followed with odd datas from some other buffer or variables or unallocated memory (in that case it may crash).
If you are using the MASM32 Editor
which conviently calls the MASM32 Assembler from a menu
use the following tip/caveat
To assemble a console app use the menu
Project -> Console Assemble & Link
if you just do
Project -> Assemble & Link
it creates a GUI app,
which wont appear to run. :U
Learned this from experiencing it first hand.
Hi
Ok.
That code given by Vortex does nothing. The program enter and exit !!!
Why ? Do you Know ?
Stay well
Regards
Quote from: RuiLoureiro on March 30, 2005, 09:14:54 PMThat code given by Vortex does nothing.
You probably builld it as a window application. You have to build it as a console application.
I just tried it with QEditor. If you use the bat files check that you use the ones with a "c" at the end ("BLDALLC.BAT").
That way it will work.
Regards
Quote from: RuiLoureiro on March 30, 2005, 09:14:54 PM
That code given by Vortex does nothing. The program enter and exit !!!
It works just as it should. If you are using QE, paste the code into QE, save it, assemble and link with the Console Assemble & Link command on the Project menu, press Ctrl+D to open a prompt, and run it.
Hi RuiLoureiro,
For your information, I never send untested code snippets to the board. Assemble the source code and link it as console application. Please let me know if you have other questions concerning the example.
Hi all
thank hitchhikr, dsousa123 for your help
thank mnemonic. Your help was appropriate and well-seen. I used a batch file with link for window application: /SUBSYSTEM:WINDOWS. I deduced it because I have the batch files BUILD.bat, BLDALL.bat, BUILDC.bat and BLDALLC.bat. This last, has LINK ... /SUBSYSTEM:CONSOLE. The problem is documentation. Or better, «good documentation». Those files are in BIN directory which hasn't any readme or info file about each file and its use. Thank you.
Thank MichaelW.
Vortex, «Nice to see you» !
[«For your information, I never send untested code snippets to the board»:
So, Code it... That's all...]
thank you for your reply. Yes i din't think that that code example
doesn't work. The problem here is my problem with the windows itself.
Now, i know console apps are different from windows apps.
-----------------------------------------------------------
It works, but:
1. Of course, it doesn't let us see «Nice to see you» !
2. The enter key close the program;
3. PgUp, Up, Down, etc. clear the work space;
4. The window is not adjusted to all the screen.
-----------------------------------------------------------
What is the meaning of each of the following LINK options ?
/EXETYPE:DYNAMIC ; what is this for ?
/FIXED[:NO] ; FIXED:NO ?
/HEAP:reserve[,commit] ; what is this for ?
/INCREMENTAL:{YES|NO} ; INCREMENTAL:NO ?
/STACK:reserve[,commit] ; what is this for ?
Whats the difference between
/SUBSYSTEM:WINDOWS and /SUBSYSTEM:WINDOWSCE ?
Whats WINDOWSCE ?
Stay well
RuiLoureiro
Hi RuiLoureiro,
Here is how to build the sample code:
\masm32\bin\ml /c /coff Sample.asm
\masm32\bin\link /SUBSYSTEM:CONSOLE Sample.obj
(http://vortex.masmcode.com/figs/Sample.JPG)
[attachment deleted by admin]
Hi Vortex,
Thank you for Sample.zip file.
Yes, in the command line my Console.exe gives exactly the same as your Sample.exe.
I understood the example given. In other words, print msg1, input to buffer, print msg2 and next the buffer.
Today i was studying functions like ReadConsoleInput ReadConsole
WriteConsole, WriteConsoleInput , SetCursorPos , GetCursorPos, SetCursorPos ShowCursor, SetCursor, etc. as well as the procedures ( StdIn, StdOut ) that are in M32Lib folder.
I don't see any application where to use these 2 functions StdIn and StdOut. I think it is necessary to read each key from keybord and control it. I need to distinguish control keys from others.
StdOut PROTO :DWORD and StdIn PROTO :DWORD,:DWORD are in MASM32.INC. The procedures ( StdIn, StdOut ) are defined in M32Lib folder. These procedures are in library MASM32.LIB too, i think ( it must ). So, to build new procedures like StdIn and StdOut, which control the set of keys we want we need to write two new procedures and put them in, for example, MASM32.inc ( protos ) and MASM32.LIB (procedures). To do this we use LIB, no ? Would you mind to give me an example of how to to this ?
;---------------------------------------------------------------------------------------------------------
stay well
regards
RuiLoureiro
http://radasm.visualassembler.com/ Well, until looking now up again at Radasm does a great job, for learning would be appropiate to have a fast
compilation in IDE. Below are the tutorials to use Radasm.
http://members.a1.net/ranmasaotome/main.html
Hi
i posted part of this matter in my topic «Window API32 documentation». Here is the file i could not attach there ( it is the first time i attach one file ). I am trying.
[attachment deleted by admin]
RuiLoureiro,
In answer to your question:
Quote
Whats the difference between /SUBSYSTEM:WINDOWS and /SUBSYSTEM:WINDOWSCE ?
Whats WINDOWSCE ?
Windows CE is a trimmed down version of Windows and is used as the OS for handheld computers. Since the screen is not standard sized (as a desktop) there needed to be a special set of APIs to handle that. There are other unique features but we do not need to get into them here. This is just to answer your question.
Paul
Hi Paul
Thank you for your reply about the subsystem «windowsCE».
Thank you, indeed.
Rui Loureiro
Hey
1. I want to share my new file cons19.zip, which is a more recent version of cons18.zip.
In this version we can write and use backspace, left, right key and we can see that KeyDown
field is the high word.
2. I modified some instructions and now the INPUT_RECORD structure seems to be:
INPUT_RECORD STRUCT
EventType WORD ? ; +0 = KEY_EVENT => key is the case
WORD ? ; +2 ????
KeyDown WORD ? ; +4 pressed = TRUE=1 ; released =FALSE=0
RepeatCount WORD ? ; +6
VirtualKeyCode WORD ? ; +8
VirtualScanCode WORD ? ;+10
CharCode WORD ? ;+12 ????
AsciiCode WORD ? ;+14 = AsciiCode = low byte
ControlKeyState WORD ? ;+16 = ControlState
INPUT_RECORD ENDS ;+18 bytes imply each InputRecord = 18 bytes
3. In conclusion, two questions: Is the documentation correct ? Or are the DLL files correct ?
What's up ?
4. All comments are welcome.
My comments are: How can we program without correct documentation ?
How can we program without your help about correct documentation ?
( All of us and all of those things should be correct )
Stay well
My best regards
RuiLoureiro
[attachment deleted by admin]
Hi RuiLoureiro. :)
By "documentation," are you referring to WIN32.HLP? If so, consider that WIN32.HLP is technically a "C" reference, so there may be some differences (especially in semantics) when using it for MASM programming. Also, I've seen at least four or five differerent versions of WIN32.HLP... the newest being dated 1997/03/14.
I would have to say the same thing. But because none had time to do a great documentation, I was trying to build one from what I learn.
I see that the TD tutorials are kind like helpful and Iczelion it's the outstanding. Since you already know asm from 8086/80286, you can even
a low-level in 32-bits since it's extended you add a E but I don't know about the extended segments, but it's not like your old days.
Movsd.com > Masmforum webte > Files > TD (Test Department tutorials).
http://webster.cs.ucr.edu/Page_TechDocs/ Officialy Doc by Microsoft but only uses Invoke statements and other things but not the Win32API as
Hutch, Iczelion and others did the job.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmasm/html/vcoriMicrosoftAssemblerMacroLanguage.asp
Here's a library but even though only explains Masm features by default by MS not by the Masm32 package.
.386, .486, .586, .686
Depend on the CPU you might have, check out your
vendor hardware. Or if you want something run at
a decent speed. NOTE: if your hardware doesn't
support it means that you had exceeded the speed
off it, and you need lower it.
Syntax:
.386, .486 , .586 , etc.
include
Use to include the masm INCLUDES and LIBRARIES.
Abbreviation:
.inc : include
.lib : library
Definition:
inc : in an include file, you will always find
a library for a specific syntax and a proper
instruction depending on the program structure,
you're going to build up.
library : contains the complete function of the
include files.
Syntax:
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
Here's a piece of my doc I was trying to build since Ms hasn't updated to .586, .686, .786 and other. Unless I haven't check in depth 6.15 link
I gave but, there's no programming guide. I can't see Masm without a good doc I decided to build one myself but I had done another thing instead of it, but I will continue it. I plan of an Standard ver of Masm and another from the Masm32 API for 32-bits mostly and 16-bits I want to
implement a higher-level too new APIs as a future preject. HLA has the best documentation for asm in support low-level 32-bits and high like
stdout, stdin, etc...
http://webster.cs.ucr.edu/
But I think it's still not enough though, I plan to make one even easier.
Luckily I got 2 interested friends who might help me and I'm going to make it a slow timing maybe even take years. Since Masm is evolving and gaining higher-level from Masm32, it will be a good idea to make it even higher.
Rui,
As far as I know the documentation is correct. The problem here is that the system expects the members of the INPUT_RECORD structure to be aligned as they would be by the Microsoft compilers, so your MASM version of the structure must duplicate this alignment.
MSDN: Windows Data Alignment on IPF, x86, and x86-64 (http://msdn.microsoft.com/library/en-us/dv_vstechart/html/vcconwindowsdataalignmentonipfx86x86-64.asp?frame=true#vcconwindowsdataalignmentonipfx86x86-64anchor2)
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; Under Windows 2000 and probably XP, to see the mouse events
; you must run the console full screen, or disable QuickEdit
; mode in the console window properties.
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
include \masm32\macros\macros.asm
MOUSE_EVENT EQU 2
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
hStdIn dd 0
nRead dd 0
INPUT_RECORD STRUCT
EventType WORD ?
WORD ? ; For alignment
UNION
KeyEvent KEY_EVENT_RECORD <>
MouseEvent MOUSE_EVENT_RECORD <>
WindowBufferSizeEvent WINDOW_BUFFER_SIZE_RECORD <>
MenuEvent MENU_EVENT_RECORD <>
FocusEvent FOCUS_EVENT_RECORD <>
ENDS
INPUT_RECORD ENDS
InputRecord INPUT_RECORD <>
.code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke GetStdHandle,STD_INPUT_HANDLE
mov hStdIn,eax
.WHILE InputRecord.KeyEvent.wVirtualKeyCode != VK_ESCAPE
invoke ReadConsoleInput,hStdIn,ADDR InputRecord,1,ADDR nRead
movzx eax,InputRecord.EventType
Switch eax
Case KEY_EVENT
print chr$("bKeyDown ")
print uhex$(InputRecord.KeyEvent.bKeyDown)
print chr$(13,10)
print chr$("wRepeatCount ")
movzx eax,InputRecord.KeyEvent.wRepeatCount
print uhex$(eax)
print chr$(13,10)
print chr$("wVirtualKeyCode ")
movzx eax,InputRecord.KeyEvent.wVirtualKeyCode
print uhex$(eax)
print chr$(13,10)
print chr$("wVirtualScanCode ")
movzx eax,InputRecord.KeyEvent.wVirtualScanCode
print uhex$(eax)
print chr$(13,10)
print chr$("uChar ")
movzx eax,InputRecord.KeyEvent.uChar
print uhex$(eax)
print chr$(13,10,13,10)
Case MOUSE_EVENT
print chr$("dwMousePosition.x ")
movzx eax,InputRecord.MouseEvent.dwMousePosition.x
print ustr$(eax)
print chr$(13,10)
print chr$("dwMousePosition.y ")
movzx eax,InputRecord.MouseEvent.dwMousePosition.y
print ustr$(eax)
print chr$(13,10)
print chr$("dwButtonState ")
print uhex$(InputRecord.MouseEvent.dwButtonState)
print chr$(13,10)
print chr$("dwControlKeyState ")
print uhex$(InputRecord.MouseEvent.dwControlKeyState)
print chr$(13,10)
print chr$("dwEventFlags ")
print uhex$(InputRecord.MouseEvent.dwEventFlags)
print chr$(13,10,13,10)
EndSw
.ENDW
exit
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Hi
i´m sorry, but i changed from Internet Provider but it lasted for 5 days (18-22\4) !
I am trying to change again.
Xor Stance, Mark:
sorry for this delay. Thank you for your reply.
MichaelW,
How are you ? I am not sure about your answer. But may be. I have one example to put here but i cannot do with this IP. It is too slow. Thank you for your example. I go to see it.
stay well
Quote from: Xor Stance on April 23, 2005, 12:25:20 AM
I don't know about the extended segments
Because they don't exist :bg
Rui,
When I assembled and tested cons19.asm, I noticed that all key events are echoed twice to the output console. Is this on purpose?
Paul
Hi
pbrennic,
i dont know well at this moment. I go to see it better. I shall give you the answer in the next post. ok ? Thank you
.........................................................................................
Another question
1. I have a table _T where i have an address of a procedure X;
2. I want that a procedure Y calls the procedure X via table _T.
How can i do this in MASM ? Is there another solution ?
.data
_T dd offset X ; This is the address of the proc X
dd ?
.code
;...................
Y proc
mov ebx, offset _T
mov eax, [ebx]
«Now i want to call EAX = to call X». How ?
ret
Y endp
;....................
X proc
ret
X endp
my regards
RuiLoureiro,
Perhaps I am missing something? I think you answerred your own question in the latest post...
Just do this:
call [eax]
hth:
Paul
Hi
Paul,
Hooo Paul, I think i tried it before but it didnt work in my XP !
It gives the error A2023:instruction operand must have size. Now, after your answer, i tried :«call dword ptr [eax]». The procedure is at address 40 1000 and eax=40 1000 but the call goes to 4110 B568 !!! [ Why ??? ]
Next, i tried :«call dword ptr ds:[eax]». The same happened. Finaly i tried «call dword ptr [ebx - Z]» where ebx is the table address (address of _T )and Z is the relative position where i have the address of procedure X.
The problem is solved: it works !!!
...............................................................
About your previous observation, it was a problem related with Input_Record structure control. Now, it is solved. The idea was one key pressed one char printed only. Now, my editor is working correctly. I think.
I am working on cons25 test example with keyboard, mouse, colour and reading and writing in any place of the screen buffer. It is going well. It is to gain some experience, to write some basic procedures (how to write and organise it better, etc. ) and to learn how the system functions work.
Thank you, Paul.
..........................................
Do you know some system procedure to clear the screen buffer in this case ?
Stay well
Not at home, doesn't
cls
work? It's in the macros of masm32 package.
To call EAX, you call EAX :green
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
include \masm32\macros\macros.asm
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
offset_testproc dd OFFSET testproc
.code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
mov ebx,OFFSET offset_testproc
mov eax,[ebx]
call eax
mov eax,input(13,10,"Press enter to exit...")
exit
testproc proc
print chr$("testproc")
ret
testproc endp
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Instead of mov eax,[ebx] / call eax why dont you just use call [ebx]
Hi
[ My problem with the internet provider i had some days ago put my mind abroad. I am sorry ].
Nilrem,
Of course, CLS ! It helps.
Sometimes we are with our mind in one direction and we forget the obvious things. So, the obvious is not the obvious. The reason why, the masm forum is a good place to stay and interchange questions and answers.
Thank you Nilrem
AeroASM,
When we are touching something, we try one thing or form, we try onother, etc. many times based on some model we have in our mind or because we begin with some model.
Thank you. The light comes from something and your reply is very important. It helps.
Hi MichaelW,
Are you upset, Michael ? [Messieur De La Palisse said the same thing: eax is equal to eax. But dont think nothing more! You can say all things that i will never upset with you. I have you in a particular good consideration].
I am like a cat after taking a good bath with hot water! When the water is cold, ... we put our legs [ mind ] to run [ into another direction ].
Coming back to asm, i ran your code and it works well [ that example is important, IMO ]. But as i said before, i followed the help from pbrennick without thinking and i have fallen in a trap [ La Palisse said eax=eax - but only when we are not tired or so !]. «call [eax]» is an indirect call. So, this is why "the call" goes to 4110 B568 and not to eax=40 1000. It takes 4110 B568 from the memory address 40 1000. It is explained [ sometimes our mind crashes, too. We already passed the 15 years old of age – i am not a whisky. What do we do in the masm forum if we did all things correctly ? So, it is better to stay here "to put" mistakes in the posts and "to talk" ... with you.
My thanks to you, Michael.
Here is the code. I will post the complete example file as soon as possible.
; Action:
; Draws the window in the _WindowBuffer and puts it in the screen buffer
;
; Input:
; ebx - window pointer
;
; Output:
; clc: OK
;
; stc: error
;
WindowMake proc
pushad
;
call WindowGetpType
jc short _eWindowMake
;
mov eax, dword ptr [ebx - WndAtrOnp$] ; color
shl eax, 16
;
mov edx, dword ptr [ebx - WndWidth$] ; width
mov ecx, dword ptr [ebx - WndHeight$] ; height
sub ecx, 2
sub edx, 2
;
mov edi, offset _WindowBuffer
call LineSupDraw
;
@@:
call LineMidDraw
loop short @B
;
call LineInfDraw
; ---------
; Add Title
; ---------
mov edi, offset _WindowBuffer
call TitleAdd
; --------------
; Add Msg or Tbl
; --------------
call WindowMsgAdd
;
; transfer to screen
; ------------------
@@:
mov ecx, dword ptr [ebx - WndHeight$] ; height
shl ecx, 16
mov eax, dword ptr [ebx - WndWidth$] ; width
mov cx, ax
call WindowPutScreen
; ---------------------
; Prc table of messages
; ---------------------
mov eax, dword ptr [ebx - WndMsgPrc$]
or eax, eax
jz short _eWindowMake
;
call dword ptr [ebx - WndMsgPrc$] ; = call eax
;
_eWindowMake: popad
ret
WindowMake endp
................................................................................................
In the following example i show some problems i had - points 1 to 7 ( Restrictions ? )
;
; 1. Symbol £: we cannot use at the beginning \ in the end of a name .
; 2. Addresses inside procedures: we cannot use them outside ?
; 3. Local variables and reserved words: for example, we cannot use «type»
; 4. Ending a procedure with «enpd»: we get too many erros [there is one].
; 5. We need 2 compilations to get the correct result after we correct one error.
; 6. invoke ProcA, ADDR PcrocB: it gives an error
; 7. The program ends in the line 78 and it reports an error in the line 87
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
include \masm32\macros\macros.asm
;...............................................................
ProcB PROTO pAdrA:DWORD
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
;£NameVar1 dd 0 ; it gives too many errors
;NameVar£ dd 0 ; it gives an error
offset_testproc dd OFFSET testproc
;...............................................................
_ADDRtestproc dd OFFSET _testproc1
dd OFFSET _testproc2
.code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
mov ebx, OFFSET offset_testproc
mov eax, [ebx]
call eax
invoke ProcB, ADDR ProcA ; undefined symbol Proc A
mov eax, input(13,10,"Press enter to exit...")
exit
;****************************************************************
Endproc proc
print chr$("Endproc")
ret
Endproc enpd
;****************************************************************
testproc proc
_testproc1 print chr$("testproc1")
ret
_testproc2: print chr$("testproc2")
ret
testproc endp
;****************************************************************
testType proc
LOCAL type:DWORD
print chr$("testproc1")
ret
testType endp
;****************************************************************
ProcA proc
print chr$("ProcA")
ret
ProcA endp
;****************************************************************
ProcB proc pAdrA:DWORD
print chr$("ProcB")
ret
ProcB endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
my best regards to all of you.
Stay well
RuiLoureiro
Hi Rui,
No, I am not upset. I was attempting to make a clever joke, and it worked about as well as it usually does.
(1)
From the MASM 6.0 Programmer's Guide:
Quote
The first character of an identifier can be an alphabetic character (A-Z) or any of these four characters: @ _ $ ?
The other characters in the identifier can be any of the characters listed above or a decimal digit (0-9)
Avoid starting an identifier with the at sign (@), because MASM 6.0 predefines some special symbols starting with @ (see Section 1.2.3). Beginning an identifier with @ may also cause conflicts with future versions of the Macro Assembler.
You cannot terminate a name with "\" because MASM recognizes "\" as a line continuation character.
(2)
If by address you mean a code label, for a code label defined in a procedure, if the label is defined with a single colon it is visible only within the procedure, and if it is defined with a double colon (for example, mylabel::) it is visible throughout the module. For a label defined outside of any procedure (in "module-level" code), a code label defined with a single colon is visible throughout the module.
(3)
You cannot use a reserved word as an identifier, but an identifier can include a reserved word (for example, type_ or _type or mytype).
(4)
The correct spelling is "endp".
(5)
?
(6)
Invoke does not support forward references to arguments. To correct this problem, create a prototype for ProcA and place it somewhere above the Invoke statement.
Hi all
Sorry, i could not reply until now.
Hi Michael:
A) How are you ?
About the joke, you succeed.
Thank you for that help. It was very good and important. :U
B) About point (6) « Invoke does not support forward references to arguments »
I think we can have another solution:
Solution 1: create a prototype for ProcA and place it somewhere above the
Invoke statement. [ Invoke, ..., ADDR ProcA, ...]
Solution 2: mov eax, offset ProcA [ ProcA anywhere ]
and then
Invoke, ..., eax, ...
................................................................................
I have been writing ( organizing and reorganizing ) procedures to print strings, tables of strings, and to open and close ( my ) windows etc., testing them etc. and, now,
i need to know how to WAIT X milliseconds [is to Open, wait X ms, Close the window ].
My windows are defined like this [is a variable like _WndWarn ]
dd 9
_MsgWarn db " Warning "
dd 25
_MsgInside db " Press a key to continue "
$SHADAVISO$ equ 1
$LARGURAAVISO$ equ 68 + $SHADAVISO$
$ALTURAAVISO$ equ 7 + 1
$BUFFERAVISO$ equ $LARGURAAVISO$ * $ALTURAAVISO$
dd 0 ; Timer / Prc to exec
...
dd Amareloclaro_Azul ; -48 Title colour
dd offset _MsgWarn ; -44 Title pointer
;
dd Cinzento_Negro ; -40 shadow colour
dd $SHADAVISO$ ; -36 Flag shadow =0,1,2
;
dd 0 ; -32 Flag buffer Full=1 /Empty=0
dd 3 ; -28 Type 1 a 5
dd Brancoclaro_Vermelho ; -24 Wnd Color
dd 10 ; -20 Wnd Column
dd 15 ; -16 Wnd Line
dd $ALTURAAVISO$ ; -12 Wnd height
dd $LARGURAAVISO$ ; -8 Wnd width
dd $BUFFERAVISO$ ; -4 Total do buffer em dwords
_WndWarn dd $BUFFERAVISO$ dup (?) ; buffer
Here are the 2 basic procedures where i need to set a proc
[call a procedure to wait EAX milliseconds].
How to do this ? Can you help me, please ?
; Action: Opens the window defined by the pointer pWnd
;
; Input: pWnd - window pointer
;
WindowOpen proc pWnd:DWORD
push esi
;
; Read window in the screen to buffer
; -----------------------------------
mov esi, pWnd
call WindowRead
jc short @F
;
; Draw new window ESI
; -------------------
call WindowMake
;
mov eax, dword ptr [esi - $WndFlgExe]
or eax, eax
jz short @F
;
cmp eax, 1
jne short @F
;
; Wait time
; ---------
mov eax, dword ptr [esi - $WndPrcExe]
[call a procedure to wait EAX miliseconds]
invoke WindowClose, esi
@@: pop esi
ret
WindowOpen endp
; --------------------------------------------------------------------------
; Action: Closes the window defined by the pointer pWnd
;
; Input: pWnd - window pointer
;
WindowClose proc pWnd:DWORD
push esi
;
mov esi, pWnd
call WindowWrite
;
pop esi
ret
WindowClose endp
...............................................................................................
Here is a sample of my work, where i used the last help from Michael:
; Action: Reads the screen buffer.
;
; Input: esi - string buffer [ dwords attr (high) + chars (low) ]
;
; Output: esi - string buffer [ dwords attr (high) + chars (low) ]
;
; Info:
; uses _hCurScreen
; The Rectangle is in _RWRectCoord
ScreenRead proc
pushad
;
call RectGetNLC
;
mov edi, _hCurScreen
invoke ReadConsoleOutput, edi, ; handle
esi, ; buffer ( DWORDS )
edx, ; Lines (H)-Cols (L)
0, ; first buffer cell
ADDR _RWRectCoord ; rectangle
jmp _eScreenWrite
ScreenRead endp
; -----------------------------------------------------------------------------
; Input: esi - string buffer [ dwords attr (high) + chars (low) ]
;
; Info:
; uses _hCurScreen [ current screen handle ]
; The Rectangle is in _RWRectCoord
ScreenWrite proc
pushad
;
call RectGetNLC
;
mov edi, _hCurScreen
invoke WriteConsoleOutput, edi, ; handle
esi, ; buffer ( DWORDS )
edx, ; Lines (H)-Cols (L)
0, ; first buffer cell
ADDR _RWRectCoord ; rectangle
_eScreenWrite:: cmp eax, 0
je short @F
;
clc
popad
ret
;
@@: stc
popad
ret
ScreenWrite endp
;-------------------------------------------------
RectGetNLC proc
;
; Coordinates
; -----------
call CoordGet
call RectCnvNLC
ret
RectGetNLC endp
; -------------------------------------------------
; Input: ebx - first cell
; edx - last cell
;
; Output: edx - number of Lines (H) + number of Columns (L)
;
RectCnvNLC proc
mov ecx, edx
shr edx, 16
inc ecx
inc edx
;
sub cx, bx
shr ebx, 16
sub dx, bx
RectCnvNLC endp
;--------------------------------------------
; Input: ebx - Lin ( high ) + Col ( low ) Left +Top = First point
; edx - = + Col + Len Right+Bottom = Last point
;
CoordGet proc
;
; Coordinates
; -----------
mov ebx, dword ptr [_RWRectCoord + 0]
mov edx, dword ptr [_RWRectCoord + 4]
ret
CoordGet endp
.......................................................................
At the end of this week, i hope to be using a new internet connection.
Thank you for all
Best regards
Stay well
Rui Loureiro
invoke sleep, 1000
?
MSDN: Sleep (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/sleep.asp)
Hi
Thank Nilrem and Michael. :U
My flash windows are working well with Sleep or SleepEx. [my file with procedures about this has already 1087 lines]
There is a problem with characters B7h, BDh, to close the corners. It is related with CodePage, i think. But i dont know how to use that function.
The Doc. said «SetConsoleCP sets the input code page used by the console .... wCodePageID = the identifier of the code page. The identifiers of the code pages available on the local computer are stored in the registry under the following key. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage»
How to access it ? I am not seeing what to do !
All good things to you.
My Thanks
Rui
Quote from: RuiLoureiro on May 17, 2005, 04:36:11 PM
There is a problem with characters B7h, BDh, to close the corners. It is related with CodePage, i think. But i dont know how to use that function.
Recently I was trying to build an ASCII table plugin for the WinAsm IDE and had much difficulty with codepages and high-ASCII characters. In short, it was a nightmare. :eek One thing I noticed was that high-ASCII characters were not being saved the same as they were written in the .asm file. You could try loading the .asm file into a hex editor and checking those bytes for correctness, or use the masm32 macro CHR$(B7) in the source instead.
Also I'm sure you know, but you can make ASCII characters by holding down ALT and keying the decimal value into the numeric keypad. (At least this is the case in the US, I assume it will work for you too.) :)
Hi Mark,
1. About ALT decimal value ( keypad ), in the masm32 editor it doesnt give any of that characters i want. For example, ALT 183, ALT 184, ALT 200, ALT 205, ALT 201. When i worked in DOS editors ( in BC ), it worked well.
2. About Code Pages, i think it is the same as in DOS, no ? For EUA and Europe, it is 437; For International is 850; Portugal is 860; Canada is 863, etc. This numbers were used in the Config.sys files.
3. When i use
invoke GetConsoleCP
invoke GetConsoleOutputCP
i get the number 352h = 850 in both cases !
4. It accepts
invoke SetConsoleCP, 860
invoke SetConsoleOutputCP, 860
but the problem is the same: chars 213, 184, 212 and 190 are not the usual and are the same in the case 850 or 860. They changed the character set. How to see the definition of each char ?
last thing: who is in the photo with one eye in one direction and the other in the other ? It looks like my son. And he does it with his eyes. I am not able.
Stay well
Hi Rui (may I call you Rui?)
Quote from: RuiLoureiro on May 19, 2005, 10:09:19 PM
1. About ALT decimal value ( keypad ), in the masm32 editor it doesnt give any of that characters i want. For example, ALT 183, ALT 184, ALT 200, ALT 205, ALT 201. When i worked in DOS editors ( in BC ), it worked well.
Yes I think the ALT-numpad trick only works in certain applications and in DOS.
I noticed that when I embedded high-ASCII characters into a source file, the values were not saved as the values I entered. i.e., an ALT-248 (0xF8h, the "degree" symbol here) would be saved as 0xB0h (but it still displays as a degree symbol on my screen...) These characters were saved the same way in the executable also... that is when I gave up understanding code pages. :)
In the Win32.hlp there is some interesting information if you search for "console."
Quote
2. About Code Pages, i think it is the same as in DOS, no ? For EUA and Europe, it is 437; For International is 850; Portugal is 860; Canada is 863, etc. This numbers were used in the Config.sys files.
That sounds right. Admittedly, I don't have much experience with codepages. I did find some old DOS information about codepages here (http://users.cybercity.dk/~bse26236/batutil/help/COUNTRY.HTM) however.
Quote
but the problem is the same: chars 213, 184, 212 and 190 are not the usual and are the same in the case 850 or 860. They changed the character set. How to see the definition of each char ?
That is a very good question. I converted my WinASM plugin into a console app which displays the ASCII table and codepage. But, changing the codepage seems to have no effect. My code must be very buggy, but maybe you can fix it. :) See the attached file.
Quote
last thing: who is in the photo with one eye in one direction and the other in the other ? It looks like my son. And he does it with his eyes. I am not able.
:lol That photo was actually part of a junkmail advertisement. I cut out the guy and "doctored" it with Paint Shop Pro. Finally: junk mail is good for something! :bg Okay because it was not entirely ethical, I changed it. :)
p.s. It is easy to "cross your eyes"... just take a pencil, stare at the eraser, and slowly bring it to your nose. Then your eyes will cross. :toothy
[attachment deleted by admin]
Aaah, here is more info from MSDN:
Quote
If the current console font is a fixed-pitch Unicode font, SetConsoleOutputCP changes the mapping of the character values into the glyph set of the font, rather than loading a separate font each time it is called. This affects how extended characters (ASCII value greater than 127) are displayed in a console window. However, if the current font is a default raster font, SetConsoleOutputCP does not affect how extended characters are displayed.
EDIT: also, the ASCII table application does show the codepage differences if the window is made fullscreen (ALT+ENTER)
Hi Mark, [ yes you may call me Rui ]
1. I saw your file Console Ascii table. It is interesting. In fullscreen i cannot see all characters. It gives the same set of characters with CodePage 437 and 860. Based in your last information, at the beginning of my program, i need to know what font is installed or i need to set one font that has the extended characters i need to use ( one that i know ). It is one more problem i have to solve at the starting point !
2. In the fullscreen mode, it is different. The character set is that i want to use ! I think i need to study something about FONTS !
3. I put my cons29.zip. The code and data is not clean because it is under development. In the future, some procedures or data structures may be different. In anyway, it is to see the codes of the keys, the structure of the key and mouse records, how to use colours, how to edit strings (my type), how to open and close (my) windows. This file was created in 8/05.
4. As you can see, ALT-numpad doesnt serve me. My windows are made by other means. In the variable that defines the window, i set a field with one type and the procedure that opens the window, makes it based on a structure i defined for each type.
5. Now, i am working in a set of all files i have, to see what i need to restructure. It is giving me more work !
Finally: i think you can help me when i was prepared to take the fonts problems again.
Stay well
[attachment deleted by admin]
Hi
My procedure KeyOnlyWait doesnt WAIT for a key when it is called by the second time.
In the Laboratory, topic "Sugestions with MSVCRT code", Jibz posts a C example waitforkeypressed from which i tried to use WaitForSingleObject.
The complete example is in the file char1.zip (an .asm & .exe).
When we remove «;» in the line where is « (1) INSERT THIS », the next KeyOnlyWait doesnt work. I am not seeing whats wrong. Any help ?
; Action:
; Clean the input buffer and wait for a key.
;
; Out:
; clc: key was pressed -> clean the input buffer -> exit
;
; stc: error
;
KeyOnlyWait proc
LOCAL nEvents:DWORD
; ------------------
; Clean input buffer
; ------------------
invoke FlushConsoleInputBuffer, _hInputBuffer
; ----------------------
; Wait for input records
; ----------------------
_iKeyOnlyWait: invoke WaitForSingleObject, _hInputBuffer, INFINITE
;0 ; returns immediately
cmp eax, WAIT_FAILED
jne short @F
;
stc
ret
;
@@: cmp eax, WAIT_OBJECT_0
jne short _iKeyOnlyWait ; no-> return
; --------------------------------------
; Object is signaled -> Number of events
; --------------------------------------
invoke GetNumberOfConsoleInputEvents, _hInputBuffer,
ADDR nEvents
cmp eax, 0
jne short _KeyOnlyWait0
;
stc ; error
ret
; ----------------
; Next input event
; ----------------
_KeyOnlyWait0: mov eax, nEvents
cmp eax, 0
je short _iKeyOnlyWait
; -----------------
; Read input buffer
; -----------------
dec eax
mov nEvents, eax
;
invoke ReadConsoleInputW, _hInputBuffer,
ADDR _InputBuffer,
1, ; read 1
ADDR _InputBuffer - 8
cmp eax, 0
jne @F ; not error
;
stc
ret
; ----------------------
; Key pressed ?
; ----------------------
@@: cmp word ptr [_InputBuffer + 0], KEY_EVENT ; EventType
jne short _KeyOnlyWait0
; -----------------------------------------------
; KEY was pressed, so Clean input buffer and EXIT
; -----------------------------------------------
invoke FlushConsoleInputBuffer, _hInputBuffer
;
clc
ret
KeyOnlyWait endp
;...............................................................................
Thanks
[attachment deleted by admin]
:bg
Thats why I posted a far smaller and more reliable polling loop version.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
wait_key proc
@@:
invoke Sleep,10
call crt__kbhit
test eax, eax
jz @B
invoke FlushConsoleInputBuffer,rv(GetStdHandle,STD_INPUT_HANDLE)
ret
wait_key endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
31 bytes in length, 0% processor usage and it does EXACTLY what its supposed to do. :green
Hi
Thanks Hutch, but the problem is that i have not msvcrt.inc and msvcrt.lib
I downloaded SP2, i installed SP2, i saw all files it contains one by one and it hasnt those files.
Moreover, i saw msvcrt.dll file in the folder \windows\system32\, used DumpPE and i studied «How to create your own masm import libraries» from iczlion. It gives more work to get those files.
Here is an exmple that shows i havent msvcrt.inc\lib
; Assembling: C:\masm32\exampl12\makecimp\vcrtdemo\vcrtdemo.asm
;...............................................................................
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: C:\masm32\exampl12\makecimp\vcrtdemo\vcrtdemo.asm
C:\masm32\exampl12\makecimp\vcrtdemo\vcrtdemo.asm(12) : fatal error A1000: canno
t open file : \masm32\include\msvcrt.inc
_
Assembly Error
Prima qualquer tecla para continuar . . .
Whould you mind posting it here ?
Thanks
Try reading the INSTALL.TXT that comes with it. It will tell you to go to exampl12 directory for the example MAKECIMP and then run the batch file MAKELIB.BAT. MSVCRT.INC & LIB will magically appear and you can then copy them to the respective include and lib directories. As usual if in doubt, read the instructions that are included in INSTALL.TXT.
Once you get SP2 installed correctly, try this code out. It does input, output and waits for you to press a key to exit.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
.code
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
call main
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc
LOCAL pinp :DWORD ; pointer for input buffer
LOCAL inbuffer[128]:BYTE ; input buffer
mov pinp, ptr$(inbuffer)
cls
mov pinp, input("Console Input Demo, type something ")
print pinp,13,10
print "Press any key to exit "
call wait_key
print chr$(13,10)
ret
main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
wait_key proc
LOCAL hConsole :DWORD
mov hConsole, rv(GetStdHandle,STD_INPUT_HANDLE)
invoke FlushConsoleInputBuffer,hConsole
@@:
invoke Sleep,10
call crt__kbhit
test eax, eax
jz @B
invoke FlushConsoleInputBuffer,hConsole
ret
wait_key endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Ok, thanks
1. Running MAKELIB.BAT in the directory masm32\makecimp i got both files msvcrt.inc and msvcrt.lib. Th first i copied to masm32\include, the second to masm32\lib. It was what i wanted.
2. I tried your exmple and here are the result:
(i searched masm32 for masm32rt.inc and isnt there )
fatal error A1000: cannot open file : \masm32\include\masm32rt.inc
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: C:\masm32\TestForum\Hutch.asm
C:\masm32\TestForum\Hutch.asm(3) : fatal error A1000: cannot open file : \masm32
\include\masm32rt.inc
_
Assembly Error
Prima qualquer tecla para continuar . . .
Hi Rui, masm32rt.inc is part of the SP2a update. :)
All it does is include the most common other libs, like user32 and macros.asm.
Nice work Ruil
I wonder why it is that I get the impression that someone has STILL not read the install.txt that came with the service pack ?
Read TFM? What do you whink we are, obedient end-users? ;) :green2
ReadFile takes in a stream of characters until Enter is pressed. How can I make it so it takes in only one character and then returns?
Hi
Obrigado
Gracias
Thanks
Mark, i downloaded SP2a just yesterday.
Striker, i am doing what i am able, step by step, without hurries.
Hutch, i usally read some info files. The problem was that i extracted SP2 to masm32 and then i lost
the global content of it.
AeroAsm, with [input parm ] nNumberOfBytesToRead = 1, i thk.
You say: «ReadFile takes in a stream of characters until Enter is pressed». Is this right ? I am not sure.
;-----------------------------------------------------------------------------------------------------------------------
I tested this wait_key in my char1.zip ( char1_1 ) and it works well.
wait_key proc
invoke FlushConsoleInputBuffer, _hInputBuffer
@@: call crt__kbhit
test eax, eax
jz @B
ret
wait_key endp
;.....................................................................................................................................
Here is other version of KeyOnlyWait used in char1a.zip. Now it works, seeming to work well.
; Action:
; Clean the input buffer and wait for a key.
;
; Out:
; clc: key was pressed -> clean the input buffer -> exit
;
; stc: error
;
KeyOnlyWait proc
LOCAL nEvents:DWORD
; ------------------
; Clean input buffer
; ------------------
invoke FlushConsoleInputBuffer, _hInputBuffer
; ----------------------
; Wait for input records
; ----------------------
_iKeyOnlyWait: invoke WaitForSingleObject, _hInputBuffer, ;INFINITE
0 ; returns immediately
cmp eax, WAIT_FAILED
jne short @F
;
stc
ret
;
@@: cmp eax, WAIT_OBJECT_0
jne short _iKeyOnlyWait ; nothing-> return
; --------------------------------------
; Object is signaled -> Number of events
; --------------------------------------
invoke GetNumberOfConsoleInputEvents, _hInputBuffer,
ADDR nEvents
cmp eax, 0
jne short _KeyOnlyWait0
;
stc ; error
ret
; ----------------
; Next input event
; ----------------
_KeyOnlyWait0: mov eax, nEvents
cmp eax, 0
je short _iKeyOnlyWait
; -----------------
; Read input buffer
; -----------------
dec eax
mov nEvents, eax
;
invoke ReadConsoleInputW, _hInputBuffer,
ADDR _InputBuffer,
20, ; read 20
ADDR _InputBuffer - 8
cmp eax, 0
jne @F ; not error
;
stc
ret
; ----------------------
; Key pressed ?
; ----------------------
@@: push esi
;
mov esi, offset _InputBuffer
xor ebx, ebx
mov ecx, dword ptr [esi - 8]
or ecx, ecx
jnz short @F
;
_zecx: pop esi
jz short _KeyOnlyWait0
;
_inxt: dec ecx
jz short _zecx
;
add ebx, 20 ; LenInputRecord = 20
;
@@: cmp word ptr [esi + ebx], KEY_EVENT ; EventType
jne short _inxt
;
cmp word ptr [esi + ebx + 4], 1 ; Key pressed
jne short _inxt
;
pop esi
; -----------------------------------------------
; KEY was pressed, so Clean input buffer and EXIT
; -----------------------------------------------
invoke FlushConsoleInputBuffer, _hInputBuffer
;
clc
ret
KeyOnlyWait endp
stay well
[attachment deleted by admin]
Hi,
I wrote another proc to wait for a key. After we press a X key, we need to release that X key to follow to the next wait loop. The X key is checked out only one time ( we can mantain it pressed, counts one time ).All keys pressed before X has been released are discarded.
The proc uses ReadConsoleInputW which waits for at least one key before returning and therefore we dont need to use GetNumberOfConsoleInputEvents.
One doubt remains: whats the correct Key_Input_Record length: 18 or 20 bytes ?
Any help ?
;....................................................................
KeyOneWait proc
pushad
mov ebx, offset _InputBuffer
cmp dword ptr [ebx - 16], 0
je short _iKeyOneWait2 ; no previous key
jne short _iKeyOneWait1
; ------------------------
; Read at least ONE RECORD
; ------------------------
@@: call RecordsFill
jc short _eKeyOneWait
_iKeyOneWait1: call KeyReleasedVrf
jc short @B ; Get more records
jnc short _iKeyOneWait2 ; Key was released (previous)
; ------------------------
; Read at least ONE RECORD
; ------------------------
@@: call RecordsFill
jc short _eKeyOneWait
_iKeyOneWait2: call KeyPressedVrf
jc short @B ; Get more records
_eKeyOneWait: popad
ret
KeyOneWait endp
;.........................................................................
RecordsFill proc
pushad
mov ebx, offset _InputBuffer
mov dword ptr [ebx - 12], ebx ; current input record
pointer
;
; One key was pressed, thus
; -------------------------
_iRecordsFill: invoke ReadConsoleInputW, _hInputBuffer,
ebx,
$MAXINPUTBUFFER$,
ADDR _InputBuffer - 8
cmp eax, 0
jne _eRecordsFill ; not error
;
stc
popad
ret
;
_eRecordsFill: cmp dword ptr [_InputBuffer - 8], 0
je short _iRecordsFill
clc
popad
ret
RecordsFill endp
;...............................................................................
Any comments ...
<LATER> When we use ALT + SPACE another window is opened to change the properties. After we close that window, the code doesnt work as before. What can i do ?
[attachment deleted by admin]