Аналог DbgPrint для user mode

Тема в разделе "WASM.WIN32", создана пользователем MoKC0DeR, 13 авг 2004.

  1. MoKC0DeR

    MoKC0DeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2003
    Сообщения:
    136
    Адрес:
    Russia
    Есть ли полный аналог dbgprint для user mode outputdebugstring не позволяет использовать %d, %s и т.д.
     
  2. MoKC0DeR

    MoKC0DeR New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2003
    Сообщения:
    136
    Адрес:
    Russia
    Сам понял что нет :dntknw:



    Сделал так:
    Код (Text):
    1.  
    2. #if DBG
    3.  
    4. #define DebugOut(_x_) DebugOut1(_x_);
    5.  
    6. #else
    7.  
    8. #define DebugOut(_x_)
    9.  
    10. #endif
    11.  
    12.  
    13. #if DBG
    14. void DebugOut1(const TCHAR* str, ...)
    15. {
    16.     TCHAR buff[1024];
    17.  
    18.     va_list parameters;
    19.     va_start(parameters, str);
    20.  
    21.     wvsprintf(buff, str, parameters);
    22.  
    23.     va_end(parameters);
    24.    
    25.     OutputDebugString(buff);
    26. }
    27. #endif
    28.  




    Однако макрос DebugOut не корректен - передается только один параметр. Как передать все ?
     
  3. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    А если так:


    Код (Text):
    1. #if DBG
    2.  
    3. void DebugOut(const TCHAR* str, ...)
    4. {
    5.     TCHAR buff[1024];
    6.  
    7.     va_list parameters;
    8.     va_start(parameters, str);
    9.  
    10.     wvsprintf(buff, str, parameters);
    11.  
    12.     va_end(parameters);
    13.    
    14.     OutputDebugString(buff);
    15. }
    16.  
    17. #else
    18.  
    19. #define DebugOut(_x_)
    20.  
    21. #endif




    Вот ещё вариант на FASM'е. Вывод происходит в дополнительное окно EDIT (так как вывожу не только сообщения об ошибках, но и всякую дополнительную инфу), но можно легко адаптировать под любые нужды. Меняет только регистр eax и имеет весьма небольшой размер.



    Параметры передаются так: непосредственно после команды call распологается строка-формат заканчивающаяся нулём, остальные параметры передаются через стек, как для wprintf. Подпрограммка сама очищает стек и возвращает управление после строки.



    Есть так же макрос для упрощения работы и избавления от возможных ошибок (несоответствие количества параметров для wsprintf и символов "%")



    Пример использования:

    LogWindow.Write 'Log window created \nHandle=%08lXh',dword[ebp]



    Символы '\n' заменяются на символы перевода строки во время компиляции.

    Строка-формат должна быть не более 255 символов, длина не проверяется.



    <font face="monospace]
    Код (Text):
    1.  
    2. ; можно без структуры обойтись,
    3. ; заменив _PUSHA.eax и sizeof._PUSHA соответствующими цифрами
    4.  
    5. struc    _PUSHA
    6. {
    7.     .edi    dd ?
    8.     .esi    dd ?
    9.     .ebp    dd ?
    10.     .esp    dd ?
    11.     .ebx    dd ?
    12.     .edx    dd ?
    13.     .ecx    dd ?
    14.     .eax    dd ?
    15. }
    16.  
    17. virtual    at 0
    18.     _PUSHA    _PUSHA
    19.     sizeof._PUSHA = $
    20. end virtual
    21.  
    22.  
    23. ;PROC    Log.Write
    24. label    Log.Write
    25.  
    26.     pusha
    27.     lea    esi,[esp+sizeof._PUSHA]
    28.     lodsd    [esi]        ;;  address after CALL
    29.                        
    30.     mov    edx,esp
    31.     dec    dh        ;;  256 bytes buffer for wvsprintf
    32.     mov    esp,edx
    33. ;    push    0A0D0D0Dh    ;;  new line
    34.  
    35.     push    esi        ;;  esi = address of VA_LIST for wvsprintf
    36.     push    eax        ;;  pFormat for wvsprintf
    37.  
    38.     xchg    eax,esi
    39.     push    1
    40.     pop    edi        ;; ardument counter
    41.  
    42. @@:    lodsb    [esi]
    43.     or    al,al
    44.     jz    .eof
    45.     cmp    al,'%'
    46.     jnz    @b
    47.     inc    edi
    48.     jmp    @b
    49.    
    50. .eof:    stdcall    [wvsprintf], edx
    51.  
    52.     ; этот код можно поменять на OutputDebugString
    53.     mov    ebx,[SendMessage]
    54.     mov    ebp,[Log.hCanvas]    ; <<======= handle окна EDIT
    55.     stdcall    ebx,ebp,EM_SETSEL,-1,-1
    56.     stdcall    ebx,ebp,EM_REPLACESEL,0,esp    ; esp = buffer
    57.  
    58. ;    pop    ecx        ;;  remove 0A0D0D0Dh DWORD
    59.     xchg    eax,esp
    60.     inc    ah
    61.     xchg    eax,esp
    62.  
    63.     mov    [esp+sizeof._PUSHA],esi    ;;  we'll return after the string
    64.     mov    [esp+_PUSHA.eax],edi
    65.  
    66.     popa
    67.     lea    eax,[esp+eax*4]
    68.     xchg    eax,esp
    69.     jmp    dword[eax]
    70. ;ENDP
    71.  
    72.  
    73. macro    Log.Write     form,[arg]
    74. {
    75.     common    local    args,char,.text
    76.             args=0
    77.     reverse if~arg eq
    78.             Push arg
    79.             args=args+1
    80.             end if
    81.     common    call    Log.Write
    82.         .text    db form,0
    83.        
    84.     repeat  $-.text-1
    85.         load    char word from .text+%-1
    86.         if char='\n'
    87.             store word 0A0Dh at .text+%-1
    88.         end if
    89.         if char and 255='%'
    90.             args=args-1
    91.         end if
    92.     end repeat
    93.         if args<>0
    94.         display '  ERROR:  "%" mismatch number of arguments.',10
    95.         !BUG    ; это должно вызвать ошибку, т.е. просто любой Неправильный набор символов
    96.         end if
    97. }
    </font><!--face-->