Многие используют функцию wsprintf(), но не все знают, что в справке msdn есть 2 ошибки, которые могут в один прекрасный день убить ваш софт.
Код (Text):
; wsprintf( // Фоpматиpует и записывает в буфеp последовательность символов ;DWORD lpOut, // Буфеp для пpиема отфоpматиpованных символов ;DWORD lpFmt, // Стpока упpавления фоpматом ; ... ); // Массив аpгументов для стpоки упpавления фоpматом ;============================================================================== ; В случае успешного завеpшения - число символов в lpOut, ; не считая 0 , в пpотивном случае - меньше, чем длина lpFmt. ;============================================================================== .386 ; .model flat,stdcall ; option casemap:none ; ;============================================================================== include c:\masm32\include\windows.inc include c:\masm32\include\kernel32.inc include c:\masm32\include\user32.inc includelib c:\masm32\lib\kernel32.lib includelib c:\masm32\lib\user32.lib ;============================================================================== .data ; ;============================================================================== lpOut db 255 dup(0) ;Здесь будет храниться результат (lpOut < 1024)! Message db "Result:",0 ;Заголовок MessageBox Unicode db 55h,0,6Eh,0,69h,0,63h,0,6Fh,0,64h,0,65h,0,0,0 ;строка в Unicode ;============================================================================== ; 1. Простейшие форматы lpFmt = %type ;============================================================================== lpFmtc db "%c",0 ;Single character lpFmtC db "%C",0 ;Single character lpFmtd db "%d",0 ;Signed decimal integer lpFmthc db "%hc",0 ;Single character lpFmthd db "%hd",0 ;Signed short integer lpFmths db "%hs",0 ;String lpFmthu db "%hu",0 ;Unsigned short integer lpFmti db "%i",0 ;Signed decimal integer lpFmtlc db "%lc",0 ;Single character lpFmtld db "%ld",0 ;Long signed integer lpFmtli db "%li",0 ;Long signed integer lpFmtls db "%ls",0 ;String lpFmtlu db "%lu",0 ;Long unsigned integer lpFmtlx db "%lx",0 ;Long unsigned hexadecimal integer lpFmtp db "%p",0 ;Win2000/XP hexadecimal pointer lpFmts db "%s",0 ;String lpFmtS db "%S",0 ;String lpFmtu db "%u",0 ;Unsigned integer lpFmtx db "%x",0 ;Unsigned hexadecimal integer ;============================================================================== ; 2. Сложные форматы lpFmt = %[-][#][0][width][.precision]type ;============================================================================== _lpFmtc db "char: %c",0 _lpFmtC db "%C is char",0 _lpFmtd db "4: %.4d",0 _lpFmthc db "%hc : %04Xh",0 _lpFmthd db "%hd is int.",0 _lpFmths db "%-45hs%8d",0 _lpFmthu db "-%.2hu",0 _lpFmti db "(%i) = %i",0 _lpFmtlc db "%lc*%lc",0 _lpFmtld db "%ld kb/s",0 _lpFmtli db "cool! , %li",0 _lpFmtls db "len 4: %.4ls",0 _lpFmtlu db "<%lu> MHz",0 _lpFmtlx db "hex: %#08lx",0 _lpFmtp db "pointer: %p",0 _lpFmts db "string: %s ,len: %i",0 _lpFmtS db "%S = %u bytes ...",0 _lpFmtu db "int: %u.%u.%u.%u",0 _lpFmtx1 db "hex: %04x-%04x-%04x-%04x",0 _lpFmtx2 db "hex: #%.2lX%.2lX%.2lX",0 _lpFmtx3 db "eax=%0.8X ebx=%0.8X ecx=%0.8X edx=%0.8X esi=%0.8X",13,10, \ "edi=%0.8X ebp=%0.8X esp=%0.8X",0 ;============================================================================== ; 3. Макрос ;============================================================================== lpFmt macro Text ; local szText ; .data ; szText byte Text,0 ; .code ; exitm <offset szText> ; endm ; ;============================================================================== .code start: ;============================================================================== ; 1. Примеры использования простейших форматов lpFmt ;============================================================================== invoke wsprintf,addr lpOut,addr lpFmtc ,65 ; call result ; "A" invoke wsprintf,addr lpOut,addr lpFmtC ,"a" ; call result ; "a" invoke wsprintf,addr lpOut,addr lpFmtd ,1 ; call result ; "1" invoke wsprintf,addr lpOut,addr lpFmthc,65 ; call result ; "A" invoke wsprintf,addr lpOut,addr lpFmthd,1 ; call result ; "1" invoke wsprintf,addr lpOut,addr lpFmths,addr Unicode ; call result ; "U" invoke wsprintf,addr lpOut,addr lpFmthu,1 ; call result ; "1" invoke wsprintf,addr lpOut,addr lpFmti ,1 ; call result ; "1" invoke wsprintf,addr lpOut,addr lpFmtlc,65 ; call result ; "A" invoke wsprintf,addr lpOut,addr lpFmtld,5872h ; call result ; "22642" invoke wsprintf,addr lpOut,addr lpFmtli,1 ; call result ; "1" invoke wsprintf,addr lpOut,addr lpFmtls,addr Unicode ; call result ; "Unicode" invoke wsprintf,addr lpOut,addr lpFmtlu,65 ; call result ; "65" invoke wsprintf,addr lpOut,addr lpFmtlx,01A2Bh ; call result ; "1a2b" invoke wsprintf,addr lpOut,addr lpFmtp ,65h ; call result ; "00000065" invoke wsprintf,addr lpOut,addr lpFmts ,addr Message ; call result ; "Result:" invoke wsprintf,addr lpOut,addr lpFmtS ,addr Unicode ; call result ; "Unicode" invoke wsprintf,addr lpOut,addr lpFmtu ,100 ; call result ; "100" invoke wsprintf,addr lpOut,addr lpFmtx ,01A2Bh ; call result ; "1a2b" ;============================================================================== ; 2. Примеры использования сложных форматов lpFmt ;============================================================================== invoke wsprintf,addr lpOut,addr _lpFmtc ,65 call result invoke wsprintf,addr lpOut,addr _lpFmtC ,"a" call result invoke wsprintf,addr lpOut,addr _lpFmtd ,1 call result invoke wsprintf,addr lpOut,addr _lpFmthc ,65,65 call result invoke wsprintf,addr lpOut,addr _lpFmthd ,1 call result invoke wsprintf,addr lpOut,addr _lpFmths ,addr Unicode,571 call result invoke wsprintf,addr lpOut,addr _lpFmthu ,1 call result invoke wsprintf,addr lpOut,addr _lpFmti ,1,1 call result invoke wsprintf,addr lpOut,addr _lpFmtlc ,65,56 call result invoke wsprintf,addr lpOut,addr _lpFmtld ,5872h call result invoke wsprintf,addr lpOut,addr _lpFmtli ,1 call result invoke wsprintf,addr lpOut,addr _lpFmtls ,addr Unicode call result invoke wsprintf,addr lpOut,addr _lpFmtlu ,666 call result invoke wsprintf,addr lpOut,addr _lpFmtlx ,01A2Bh call result invoke wsprintf,addr lpOut,addr _lpFmtp ,65h call result invoke wsprintf,addr lpOut,addr _lpFmts ,addr Message,sizeof Message-1 call result invoke wsprintf,addr lpOut,addr _lpFmtS ,addr Unicode,sizeof Unicode call result invoke wsprintf,addr lpOut,addr _lpFmtu ,100 call result invoke wsprintf,addr lpOut,addr _lpFmtx1 ,01A2Bh call result invoke wsprintf,addr lpOut,addr _lpFmtx2 ,01A2Bh call result invoke wsprintf,addr lpOut,addr _lpFmtx3 ,eax,ebx,ecx,edx,esi,edi,ebp,esp call result ;============================================================================== ; 3. Пример c использованием макроса ;============================================================================== invoke wsprintf,addr lpOut,lpFmt("%ld kb/s"),5872h call result invoke wsprintf,addr lpOut,lpFmt("Alert, sindrom vachtera detected, %li"),1 call result ;============================================================================== invoke ExitProcess,0 ;============================================================================== ; Вывод результата ;============================================================================== result proc invoke MessageBox,0,addr lpOut,addr Message,MB_OK ret result endp ;============================================================================== end start
Вывод через wsprintf на assemblere
Дата публикации 14 сен 2022
| Редактировалось 16 сен 2022