News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Not satisfied SetTime?

Started by ikudesnik, September 03, 2015, 10:48:56 PM

Previous topic - Next topic

ikudesnik

.386 ; 32-битный режим
.model flat, stdcall ; компиляция в exe-файл с возможностью вызова API
option casemap :none ; неразличение прописных и строчных символов



; содержит значения констант
include C:\masm32\include\windows.inc ; STD_INPUT_HANDLE,
; STD_OUTPUT_HANDLE
include \masm32\include\winmm.inc
include <\masm32\include\kernel32.inc>
include <\masm32\include\user32.inc>

includelib <\masm32\lib\kernel32.lib>
includelib <\masm32\lib\user32.lib>
includelib c:\masm32\lib\winmm.lib
.const

MEMSIZE equ 65535

.data ; сегмент данных

hfile_write dd ?
hfile_read dd ?
buff_file db 0

file_read db "file_read.txt",0
file_write db "file_write.txt",0
file_read_size dd ?  ;размер файла
size_file_read dd ?  ;количество считанных байт
ByteWritten dd ?

hConsoleInput DWORD ? ; переменные для хранения хэндлов ввода и вывода,
hConsoleOutput DWORD ? ; названия этих переменных могут быть другими

            ; буфер 1 байт (со значением 0)
Buffer byte 1 dup (0) ; для вода с клавиатуры 1 символа,
; название буфера может быть другим

NumberOfCharsRead DWORD ? ; переменные для записи числа фактически
NumberOfCharsWritten DWORD ? ; введенных и выведенных символов,
; названия этих переменных могут быть другими

hMemory HANDLE ?
pMemory DWORD ?


msg1 byte "Задача выполненна успешно!" ; строковая переменная

; строковая переменная
msg2 byte "Нажмите Enter, чтобы выйти...", 0 ; заканчивается нулем,
; так как она будет передана
; API-функции CharToOem


msg1310 byte 13, 10 ; перевод строки
ERROR_CreateFile byte "ERROR_CreateFile",0
ERROR_GetFileSize byte "ERROR_GetFileSize",0
ERROR_VirtualAlloc byte "ERROR_VirtualAlloc",0
ERROR_ReadFile byte "ERROR_ReadFile",0
ERROR_WriteFile byte "ERROR_WriteFile",0

IDTime dword ?



.code ; сегмент кода
mytime proc hWnd, uMsg, idEvent, dwTime: DWORD ;hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD;
    pushad
    mov ecx,file_read_size
mov esi,pMemory
loop1:
movzx eax,byte ptr [esi]
mov eax,'f'
mov byte ptr [esi],al
;mov dword ptr [esi],eax
loop2:
inc esi
loop loop1
popad
    ret
mytime endp



start:


invoke CreateFile, ADDR file_write,
GENERIC_WRITE or GENERIC_READ,
  FILE_SHARE_WRITE or FILE_SHARE_READ,
                         NULL,
                CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
                         NULL
;CMP EAX,-1
;JE _ERROR_CreateFile
mov hfile_write, eax

invoke CreateFile, ADDR file_read,                        ;открываем файл для чтения для получения дискриптора файла
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY,
NULL
;CMP EAX,-1
;JE _ERROR_CreateFile
mov hfile_read, eax

invoke GetFileSize, hfile_read, NULL                      ;получаем размер файла
;CMP EAX,0
;JE _ERROR_GetFileSize
mov file_read_size,eax
;mov ecx,eax


invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,MEMSIZE
mov  hMemory,eax ;функция возвращает хэндл на запрошенный блок памяти

invoke GlobalLock,hMemory
mov  pMemory,eax ;возвращает указатель на блок памяти
;mov  esi,eax



invoke ReadFile, hfile_read,                          ;считываем данные с файла
pMemory, ;Адрес буфера
file_read_size, ;MEMSIZE-1,  ;Размер буфера или сколько байтов нужно прочитать
ADDR size_file_read,  ; Адрес переменной, в которую записывается реальное количество прочитанных данных
NULL
;CMP EAX,0
;JE  _ERROR_ReadFile



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

invoke SetTimer, NULL,NULL, 1000, ADDR mytime
mov IDTime,eax
invoke KillTimer,NULL, [IDTime]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



invoke WriteFile, hfile_write, 
pMemory, ; Указатель на буфер, содержащий данные, которые будут записаны в файл
size_file_read,     ; Число байтов, которые будут записаны в файл
ADDR size_file_read,;ADDR ByteWritten,   ;Указатель на переменную, которая получает число записанных байтов
NULL
;CMP EAX,0
;JE _ERROR_WriteFile

invoke CloseHandle, hfile_read
invoke CloseHandle, hfile_write

invoke GlobalUnlock,pMemory
invoke GlobalFree,hMemory





invoke AllocConsole ; запрашиваем у Windows консоль

invoke GetStdHandle, STD_INPUT_HANDLE ; получаем хэндл консоли для ввода
mov hConsoleInput, EAX ; записываем хэндл в переменную

invoke GetStdHandle, STD_OUTPUT_HANDLE ; получаем хэндл консоли для вывода
mov hConsoleOutput, EAX ; записываем хэндл в переменную

invoke WriteConsoleA, ; переводим строку в консоли
                      hConsoleOutput, ; хэндл вывода
                        ADDR msg1310, ; адрес строки msg1310
                      SIZEOF msg1310, ; размер строки msg1310
           ADDR NumberOfCharsWritten, ; сюда функция запишет число символов
                                   0 ; lpReserved передаем, как ноль

invoke CharToOem, ADDR msg1, ADDR msg1

invoke WriteConsoleA, ; пишем " Hello, World!"
                      hConsoleOutput,
                           ADDR msg1,
                         SIZEOF msg1,
           ADDR NumberOfCharsWritten,
                                   0



invoke WriteConsoleA, ; переводим строку
                      hConsoleOutput,
                        ADDR msg1310,
                      SIZEOF msg1310,
           ADDR NumberOfCharsWritten,
                                   0



;invoke CharToOem, ADDR msg2, ADDR msg2 ; перекодируем Win1251 -> DOS



invoke WriteConsoleA, ; пишем " Нажмите Enter, чтобы выйти..."
                      hConsoleOutput,
                           ADDR msg2,
                   (SIZEOF msg2) - 1, ; уменьшаем размер строки msg2 на 1 (из-за нуля)
           ADDR NumberOfCharsWritten,
                                   0



invoke ReadConsoleA, ; ожидаем ввода в консоль
                      hConsoleInput, ; хэндл ввода
                        ADDR Buffer, ; адрес буфера
                                  1, ; вводим 1 символ
             ADDR NumberOfCharsRead, ; сюда функция запишет число символов
                                  0 ; lpReserved передаем, как ноль



invoke ExitProcess, 0 ; сообщаем системе, что программа окончена



end start ; завершает сегмент кода
   

avcaballero

Wow, reading Russian is a bit hard, not as Spanish, the most beautiful and easy language in the world, or... yes, English if there's nothing else  :redface:

rrr314159

hello ikudesnik,

I'm not satisfied with SetTime either! For a better way to measure time, use RDTSC; see \masm32\macros\timers.asm for an example. Not sure if that's what you're looking for?
I am NaN ;)

jj2007

- you kill SetTimer, so how should it work?
- SetTimer requires a Windows loop, i.e. a GUI, not a console

.386; 32-bit mode
.model flat, stdcall; compile in exe-file of the API call with the possibility
option casemap: none; lack of distinction between uppercase and lowercase characters

; It provides constant values
include \ masm32 \ include \ windows.inc; STD_INPUT_HANDLE,
; STD_OUTPUT_HANDLE
include \ masm32 \ include \ winmm.inc
include <\ masm32 \ include \ kernel32.inc>
include <\ masm32 \ include \ user32.inc>

includelib <\ masm32 \ lib \ kernel32.lib>
includelib <\ masm32 \ lib \ user32.lib>
includelib \ masm32 \ lib \ winmm.lib
.const
MEMSIZE equ 65535

.data; data segment

hfile_write dd?
hfile_read dd?
buff_file db 0

file_read db "file_read.txt", 0
file_write db "file_write.txt", 0
file_read_size dd? ;file size
size_file_read dd? , the number of bytes read
ByteWritten dd?

hConsoleInput DWORD? ; variables to hold the handles input and output,
hConsoleOutput DWORD? ; the names of these variables may be different

; 1 byte buffer (with value 0)
1 Buffer byte dup (0); for water Keyboard symbol 1,
; the name of the buffer may be different

NumberOfCharsRead DWORD? ; to record the number of variables actually
NumberOfCharsWritten DWORD? ; input and output symbols,
; the names of these variables may be different

hMemory HANDLE?
pMemory DWORD?


msg1 byte "mission accomplished successfully!" ; string variable

; string variable
msg2 byte "Press Enter, to come out ...", 0; It ends with a zero,
; as it will be transferred
; API-function CharToOem


msg1310 byte 13, 10; line translation
ERROR_CreateFile byte "ERROR_CreateFile", 0
ERROR_GetFileSize byte "ERROR_GetFileSize", 0
ERROR_VirtualAlloc byte "ERROR_VirtualAlloc", 0
ERROR_ReadFile byte "ERROR_ReadFile", 0
ERROR_WriteFile byte "ERROR_WriteFile", 0

IDTime dword?

.code; code segment
mytime proc hWnd, uMsg, idEvent, dwTime: DWORD; hWnd: DWORD, uMsg: DWORD, wParam: DWORD, lParam: DWORD;
    pushad
    mov ecx, file_read_size
mov esi, pMemory
loop1:
movzx eax, byte ptr [esi]
mov eax, 'f'
mov byte ptr [esi], al
; mov dword ptr [esi], eax
loop2:
inc esi
loop loop1
popad
    ret
mytime endp

start:

invoke CreateFile, ADDR file_write,
GENERIC_WRITE or GENERIC_READ,
FILE_SHARE_WRITE or FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
; CMP EAX, -1
; JE _ERROR_CreateFile
mov hfile_write, eax

invoke CreateFile, ADDR file_read,; open the file to read for diskriptora file
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY,
NULL
; CMP EAX, -1
; JE _ERROR_CreateFile
mov hfile_read, eax

invoke GetFileSize, hfile_read, NULL; get the file size
; CMP EAX, 0
; JE _ERROR_GetFileSize
mov file_read_size, eax
; mov ecx, eax


invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, MEMSIZE
mov hMemory, eax; function returns a handle to the requested memory block

invoke GlobalLock, hMemory
mov pMemory, eax; returns a pointer to the memory block
; mov esi, eax



invoke ReadFile, hfile_read,; read data from the file
pMemory,; address buffer
file_read_size,; MEMSIZE-1, buffer size, or how many bytes you need to read
ADDR size_file_read,; Address of the variable which is written the actual number of read data
NULL
; CMP EAX, 0
; JE _ERROR_ReadFile

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

invoke SetTimer, NULL, NULL, 1000, ADDR mytime
mov IDTime, eax
invoke KillTimer, NULL, [IDTime]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

invoke WriteFile, hfile_write,
pMemory,; Pointer to the buffer containing the data to be written to a file
size_file_read,; The number of bytes that will be written to a file
ADDR size_file_read,; ADDR ByteWritten,; Pointer to a variable that receives the number of bytes written
NULL
; CMP EAX, 0
; JE _ERROR_WriteFile

invoke CloseHandle, hfile_read
invoke CloseHandle, hfile_write

invoke GlobalUnlock, pMemory
invoke GlobalFree, hMemory

invoke AllocConsole; queries the Windows console

invoke GetStdHandle, STD_INPUT_HANDLE; We get the handle console input
mov hConsoleInput, EAX; write handle variable

invoke GetStdHandle, STD_OUTPUT_HANDLE; We obtain a handle to the console output
mov hConsoleOutput, EAX; write handle variable

invoke WriteConsoleA,; newline console
                      hConsoleOutput,; handle output
                        ADDR msg1310,; address line msg1310
                      SIZEOF msg1310,; line size msg1310
           ADDR NumberOfCharsWritten,; here the function will record the number of characters
                                   0; lpReserved pass as zero

invoke CharToOem, ADDR msg1, ADDR msg1

invoke WriteConsoleA,; write "Hello, World!"
                      hConsoleOutput,
                           ADDR msg1,
                         SIZEOF msg1,
           ADDR NumberOfCharsWritten,
                                   0

invoke WriteConsoleA,; newline
                      hConsoleOutput,
                        ADDR msg1310,
                      SIZEOF msg1310,
           ADDR NumberOfCharsWritten,
                                   0

; invoke CharToOem, ADDR msg2, ADDR msg2; recoding Win1251 -> DOS

invoke WriteConsoleA,; write "Press Enter, to come out ..."
                      hConsoleOutput,
                           ADDR msg2,
                   (SIZEOF msg2) - 1; reduce the size of line msg2 1 (due to zero)
           ADDR NumberOfCharsWritten,
                                   0

invoke ReadConsoleA,; I look forward to the console
                      hConsoleInput,; handle input
                        ADDR Buffer,; buffer address
                                  1, ; enter 1 character
             ADDR NumberOfCharsRead,; here the function will record the number of characters
                                  0; lpReserved pass as zero

invoke ExitProcess, 0; We tell the system that the program is over

end start; completes code segment

dedndave

even if in Russian, tell us what you want and what is not working   :t
we can use google translate, and get a pretty good idea

ikudesnik

How to organize a loop: every two seconds to process one character in the console?

dedndave

you can use Sleep

    mov     ebx,10
    .repeat
        lea     eax,[ebx-1]
        print   str$(eax),32
        INVOKE  Sleep,2000     ;time in mS
        dec     ebx
    .until ZERO?
    print  chr$(13,10)

ikudesnik

It is necessary to use the API function with timer :(

dedndave

i guess what you want to do is use SetTimer and KillTimer
generally, we use it to send WM_TIMER messages
but, that's not the only way to use it

https://msdn.microsoft.com/en-us/library/windows/desktop/ms644906%28v=vs.85%29.aspx

another way to use it is with a callback function
when the time elapses, a PROC is called
notice that the timer function is passed 4 dword arguments

https://msdn.microsoft.com/en-us/library/windows/desktop/ms644907%28v=vs.85%29.aspx

i can make an example, but not tonight - it's bed time   :P

ikudesnik

Can I use timesetevent?
Can you give an example of my problem?

avcaballero

Maybe this may help. Fasm syntax, sorry, don't have masm at hand now. Regards.

avcaballero

The file. Isn't possible to attach a file on editing a post?

ikudesnik

I'm probably a fool-I can not understand :icon_eek:

it is necessary to call a function
invoke timeSetEvent,20000,0,addr mytime,TIME_ONESHOT,TIME_CALLBACK_FUNCTION
mov IDTime,eax
invoke timeKillEvent, IDTime

After 20 seconds, the procedure "mytime" should work
but it does not work  :(

ikudesnik

.386 ; 32-битный режим
.model flat, stdcall ; компиляция в exe-файл с возможностью вызова API
option casemap :none ; неразличение прописных и строчных символов



; содержит значения констант
include C:\masm32\include\windows.inc ; STD_INPUT_HANDLE,
; STD_OUTPUT_HANDLE
include \masm32\include\winmm.inc
include <\masm32\include\kernel32.inc>
include <\masm32\include\user32.inc>

includelib <\masm32\lib\kernel32.lib>
includelib <\masm32\lib\user32.lib>
includelib c:\masm32\lib\winmm.lib
.const

MEMSIZE equ 65535

.data ; сегмент данных

hfile_write dd ?
hfile_read dd ?
buff_file db 0

file_read db "file_read.txt",0
file_write db "file_write.txt",0
file_read_size dd ?  ;размер файла
size_file_read dd ?  ;количество считанных байт
ByteWritten dd ?

hConsoleInput DWORD ? ; переменные для хранения хэндлов ввода и вывода,
hConsoleOutput DWORD ? ; названия этих переменных могут быть другими

            ; буфер 1 байт (со значением 0)
Buffer byte 1 dup (0) ; для вода с клавиатуры 1 символа,
; название буфера может быть другим

NumberOfCharsRead DWORD ? ; переменные для записи числа фактически
NumberOfCharsWritten DWORD ? ; введенных и выведенных символов,
; названия этих переменных могут быть другими

hMemory HANDLE ?
pMemory DWORD ?


msg1 byte "Задача выполненна успешно!" ; строковая переменная

; строковая переменная
msg2 byte "Нажмите Enter, чтобы выйти...", 0 ; заканчивается нулем,
; так как она будет передана
; API-функции CharToOem


msg1310 byte 13, 10 ; перевод строки
ERROR_CreateFile byte "ERROR_CreateFile",0
ERROR_GetFileSize byte "ERROR_GetFileSize",0
ERROR_VirtualAlloc byte "ERROR_VirtualAlloc",0
ERROR_ReadFile byte "ERROR_ReadFile",0
ERROR_WriteFile byte "ERROR_WriteFile",0

IDTime dword ?



.code ; сегмент кода
mytime proc ;hWnd, uMsg, idEvent, dwTime: DWORD ;hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD;
    pushad
    mov ecx,file_read_size
mov esi,pMemory
loop1:
movzx eax,byte ptr [esi]
mov eax,'f'
mov byte ptr [esi],al
;mov dword ptr [esi],eax
loop2:
inc esi
loop loop1
popad
    ret
    invoke timeKillEvent, IDTime
mytime endp



start:


invoke CreateFile, ADDR file_write,
GENERIC_WRITE or GENERIC_READ,
  FILE_SHARE_WRITE or FILE_SHARE_READ,
                         NULL,
                CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
                         NULL
;CMP EAX,-1
;JE _ERROR_CreateFile
mov hfile_write, eax

invoke CreateFile, ADDR file_read,                        ;открываем файл для чтения для получения дискриптора файла
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY,
NULL
;CMP EAX,-1
;JE _ERROR_CreateFile
mov hfile_read, eax

invoke GetFileSize, hfile_read, NULL                      ;получаем размер файла
;CMP EAX,0
;JE _ERROR_GetFileSize
mov file_read_size,eax
;mov ecx,eax


invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,MEMSIZE
mov  hMemory,eax ;функция возвращает хэндл на запрошенный блок памяти

invoke GlobalLock,hMemory
mov  pMemory,eax ;возвращает указатель на блок памяти
;mov  esi,eax



invoke ReadFile, hfile_read,                          ;считываем данные с файла
pMemory, ;Адрес буфера
file_read_size, ;MEMSIZE-1,  ;Размер буфера или сколько байтов нужно прочитать
ADDR size_file_read,  ; Адрес переменной, в которую записывается реальное количество прочитанных данных
NULL
;CMP EAX,0
;JE  _ERROR_ReadFile



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
invoke timeSetEvent,20000,0,addr mytime,TIME_ONESHOT,TIME_CALLBACK_FUNCTION ;http://rusapi.narod.ru/timeSetEvent.htm
mov IDTime,eax

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



invoke WriteFile, hfile_write, 
pMemory, ; Указатель на буфер, содержащий данные, которые будут записаны в файл
size_file_read,     ; Число байтов, которые будут записаны в файл
ADDR size_file_read,;ADDR ByteWritten,   ;Указатель на переменную, которая получает число записанных байтов
NULL
;CMP EAX,0
;JE _ERROR_WriteFile

invoke CloseHandle, hfile_read
invoke CloseHandle, hfile_write

invoke GlobalUnlock,pMemory
invoke GlobalFree,hMemory





invoke AllocConsole ; запрашиваем у Windows консоль

invoke GetStdHandle, STD_INPUT_HANDLE ; получаем хэндл консоли для ввода
mov hConsoleInput, EAX ; записываем хэндл в переменную

invoke GetStdHandle, STD_OUTPUT_HANDLE ; получаем хэндл консоли для вывода
mov hConsoleOutput, EAX ; записываем хэндл в переменную

invoke WriteConsoleA, ; переводим строку в консоли
                      hConsoleOutput, ; хэндл вывода
                        ADDR msg1310, ; адрес строки msg1310
                      SIZEOF msg1310, ; размер строки msg1310
           ADDR NumberOfCharsWritten, ; сюда функция запишет число символов
                                   0 ; lpReserved передаем, как ноль

invoke CharToOem, ADDR msg1, ADDR msg1

invoke WriteConsoleA, ; пишем " Hello, World!"
                      hConsoleOutput,
                           ADDR msg1,
                         SIZEOF msg1,
           ADDR NumberOfCharsWritten,
                                   0



invoke WriteConsoleA, ; переводим строку
                      hConsoleOutput,
                        ADDR msg1310,
                      SIZEOF msg1310,
           ADDR NumberOfCharsWritten,
                                   0



;invoke CharToOem, ADDR msg2, ADDR msg2 ; перекодируем Win1251 -> DOS



invoke WriteConsoleA, ; пишем " Нажмите Enter, чтобы выйти..."
                      hConsoleOutput,
                           ADDR msg2,
                   (SIZEOF msg2) - 1, ; уменьшаем размер строки msg2 на 1 (из-за нуля)
           ADDR NumberOfCharsWritten,
                                   0



invoke ReadConsoleA, ; ожидаем ввода в консоль
                      hConsoleInput, ; хэндл ввода
                        ADDR Buffer, ; адрес буфера
                                  1, ; вводим 1 символ
             ADDR NumberOfCharsRead, ; сюда функция запишет число символов
                                  0 ; lpReserved передаем, как ноль



invoke ExitProcess, 0 ; сообщаем системе, что программа окончена



end start ; завершает сегмент кода

jj2007

It is important to understand that SetTimer needs a message loop to work. In general, a console app with no WndProc doesn't have a message loop. But even a simple MessageBox will create one:

include \masm32\include\masm32rt.inc
.code
CbTimer proc hwnd:DWORD, uMsg:DWORD, PMidEvent:DWORD, dwTime:DWORD
  print "*"
  ret
CbTimer endp
start:
   invoke SetTimer, 0, 123, 50, CbTimer
   inkey "hit any key, then Escape"
   .Repeat
    print "#"
invoke Sleep, 100 ; this will NOT allow the timer callback to execute
invoke GetKeyState, VK_ESCAPE
test ah, ah
   .Until Sign?
   MsgBox 0, "Congrats", "SetTimer in console app:", MB_OK
   exit
end start


An alternative is to create a program with WndProc etc but to build it as console app. SetTimer will work just fine, and you can hide the main window if you don't want it.