Почему эта прога: Код (Text): #include <stdio.h> void main () { for (int i=0;i<500;i++) printf("\t\t\b\b\b" ); } Убиваеть XP???
_DEN_ Я компилил ... Intel С++ 7.0, VC++ Toolkit 2003, MS VC++ 2005 Express Beta. Console application. Не падает.
q_q Ну значит не зря MS свои сервиспаки выпускает У меня просто XP Professional. Запускаю прогу, сначала пропадает звук, через секунду черный экран, еще через долю секунды - синий
попробовал на асме - работает в таком виде: Код (Text): .data mess_l dd ? death_mess db 9,9,8,8,8,0 MESS_LENGTH equ $ - death_mess LOOPS_COUNT equ 4 .code _start: push STD_OUTPUT_HANDLE call GetStdHandle mov ebx,eax mov edi,LOOPS_COUNT death_loop: push 0 push offset mess_l push MESS_LENGTH push offset death_mess push ebx call WriteConsole dec edi jnz death_loop push 0 call ExitProcess end _start поковырямся во WriteConsole...
q_q Ну, типа sz-строка. Или в консоль можно писать, просто указав количество выводимых символов? Не знаю, это вообще моя первая консольная программа. Дошел до ntoskernel!WaitForMutexOject(), глубже копать нету сил, замучили перезагрузки. Насчет почему: \b - символ отката, видимо он декрементирует накой-то указатель в 0-м кольце, и что-то затирается. В нашем случае '\b' на один больше, чем '\t', а со строкой "\t\t\t\b\b\b" все работает нормально. ЗЫ. Под Айсом прога убивает винду на первой итерации.
vinnie_pooh В третьем параметре указывается количество записываемых символов (не путать с байтами), поэтому необходимость в определении конца строки отсутствует.
q_q спасибо, у меня в справочнике по WinAPI нет описания WriteConsole(). наверное, потому что еще существует WriteConsoleW.
Почему убивает ХР? Потому что ХР - дерьмо плюшевое. ЗЫ: не воспринимайте меня всерьез - я слишком пъян.
Посмотрел в сорцах винды. WriteConsoleOutput вызывает WriteConsoleOutputInternal. А там муть какая-то... Но никаких намеков на \b или \t я не увидел... Вот файл: %W2K_SRC_ROOT%\private\ntos\w32\ntcon\client\iostubs.c Там есть тело WriteConsoleOutputInternal. Вот еще: %W2K_SRC_ROOT%\private\ntos\w32\ntcon\client\stream.c Там описана WriteConsole и WriteConsoleInternal. В ней видно, что юзается несколько функций, похоже native api, Может дело в них. Их имена: - CsrAllocateCaptureBuffer - CsrCaptureMessageBuffer - RtlCopyMemory - CsrClientCallServer - CsrFreeCaptureBuffer Никакие другие функции внутри WriteConsoleInternal вроде не юзаются. Скорее всего дело в одной из них. Я бы и сами файлы припостил, да боюсь товарищ Беспощадный Даос обидется
Хмм.. а почему именно WriteConsole? Код (Text): extern "C" int __cdecl printf(const char * format, ...) { char szBuff[1024]; int retValue; DWORD cbWritten; va_list argptr; va_start( argptr, format ); retValue = wvsprintf( szBuff, format, argptr ); va_end( argptr ); WriteFile( GetStdHandle(STD_OUTPUT_HANDLE), szBuff, retValue, &cbWritten, 0 ); return retValue; }
S_T_A_S_ Imho wvsprintf/wsprintf нельзя считать достойной заменой printf'у - не поддерживают вывод вещественных и 64-хбитных чисел. А WriteFile в отличие от WriteConsole не делится на UNICODE и ANSI версии, т.е. необходимы дополнительные усилия.
Если вызвать WriteFile с хендлом стандартного вывода в 1-м параметре, то мы как раз в WriteConsole и попадаем. вот проверка на std_out_handle: Код (Text): .text:77E94A7E mov eax, edi .text:77E94A80 and eax, 10000003h .text:77E94A85 cmp eax, 3 .text:77E94A88 jz short loc_77E94AD7 этот jz перескакивает вызов NtWriteFile, а дальше: Код (Text): .text:77E94AD7 loc_77E94AD7: ; CODE XREF: WriteFile+64j .text:77E94AD7 push [ebp+lpReserved] ; lpReserved .text:77E94ADA push ebx ; lpNumberOfCharsWritten .text:77E94ADB push [ebp+nNumberOfCharsToWrite] ; nNumberOfCharsToWrite .text:77E94ADE push [ebp+lpBuffer] ; lpBuffer .text:77E94AE1 push edi ; hConsoleOutput .text:77E94AE2 call WriteConsoleA .text:77E94AE7 jmp short loc_77E94AC6 .text:77E94AE7 WriteFile endp