На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Помните, что у нас есть FAQ раздела Assembler и Полезные ссылки. Посмотрите, возможно, там уже имеется решение вашего вопроса.

3. Настоятельно рекомендуем обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "Ассемблер" будут отправляться в Корзину для мусора.
  3.2. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).
  3.3. Нежелательно поднимать старые темы (не обновлявшиеся более года) без веской на то причины.

Не забывайте также про главные Правила форума!

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> КТЗ!, [К]омандная строка+[Т]аймер высокого разрешения+[З]апуск процесса
    Всем привет, особенно Jin X (с целью подмазаться) ! :lol:

    В уиндовс так не хватает линуксовой команды 'time' ... вот я и подумал, а почему бы ее не запилить на ассемблере?! Но, увы, столько времени утекло - где я, и где ассемблер :-? Поэтому просьба, как в том фильме "вельми понеже, паки-паки, иже херувимы" (С) поделитесь наработками, плс!

    Нужно:

    * считать argv[1]
    * запустить таймер высокого разрешения
    * запустить argv[1] как процесс
    * остановить таймер высокого разрешения
    * вернуть или затраченное время процессом, или сообщение об ошибке запуска

    Почему на асме? С++ компилеры выдают жЫрноту, меня это бесит - тут на максмимум 3кб размер исполняемого файта. Ассемблер интересен. Можно запилить на голом Си+плюшки (используя к примеру LCC) ... но это уже будет другая песня не об этом.

    И еще ... если такая возможность есть - не линковать CRT.DLL. Чем "автономней исполняемый модуль - тем лучше, и пофик на лишний килобайт.
      Цитата JoeUser @
      В уиндовс так не хватает линуксовой команды 'time'
      Есть QueryPerformanceCounter и QueryPerformanceFrequency.
      Т.е. читаем QueryPerformanceCounter до запуска, QueryPerformanceCounter после запуска, считаем разницу и делим на QueryPerformanceFrequency, получаем секунды.

      Запуск – CreateProcess.

      Вывести можно, если писать на MASM32 через функции встроенной библиотеки: StdOut, dw2a (или wsprintf – это не msvcrt).
      А чем, собственно, msvcrt не устраивает? Проще всего ж использовать printf.

      Но не знаю, насколько такой таймер реально оправдан, ведь на запуск тоже уйдёт какое-то время и внесёт свою погрешность, так что, может, GetTickCount достаточно?
        цыгвин
          Jin X, пасип ... я позже зайду! :lol:
            Цитата Gonarh @
            цыгвин
            Иван Иваныч?
              Цитата Gonarh @
              цыгвин

              Cygwin? Ай донт андерстенд!
                Цитата JoeUser @
                Cygwin?

                Яя, натюрлих.
                  Цитата JoeUser @
                  Почему на асме? С++ компилеры выдают жЫрноту, меня это бесит - тут на максмимум 3кб размер исполняемого файта.
                  Гм, "жЫрнота" будет везде:
                  С++, писано за 10 минут, один сеанс отладки, размер образа от Студии 214к
                  ExpandedWrap disabled
                    #include <windows.h>
                    #
                    #include <chrono>
                    #include <iostream>
                    #include <vector>
                    #include <string>
                     
                    int main(int argn, char *argv[])
                    {
                      PROCESS_INFORMATION procInfo;
                      STARTUPINFO         startInfo= { sizeof(startInfo), NULL, NULL, NULL, 0, 0, 0, 0, 0, 0,
                                                        0, STARTF_FORCEOFFFEEDBACK, 0, 0, NULL,
                                                        NULL, NULL, NULL};
                     
                      std::string cmdLine;
                     
                      for (int i = 1; i < argn; ++i)
                        cmdLine.append(argv[i]) += ' ';
                      if (cmdLine.empty())
                        return std::cout << "App for run is absent\n",
                               1;
                     
                      std::vector<char> appName(std::begin(cmdLine), std::end(cmdLine));
                     
                      appName[appName.size()-1] = '\0';
                     
                      auto start = std::chrono::system_clock::now();
                     
                      if (CreateProcess(NULL, &appName.front(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL,
                                        &startInfo, &procInfo) == 0)
                        return std::cout << "Error of " << argv[1] << " launch. Error code is " << GetLastError() << '\n',
                               1;
                      else
                      {
                        CloseHandle(procInfo.hThread);
                        WaitForSingleObject(procInfo.hProcess, INFINITE);
                     
                        auto now = std::chrono::system_clock::now();
                     
                        CloseHandle(procInfo.hProcess);
                        std::cout << "Time of run is "
                                  << std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count()
                                  << " ms.\n";
                      }
                     
                      return 0;
                    }

                  С, писано за 35 минут, 6 сеансов отладки, размер образа от Студии 100к
                  ExpandedWrap disabled
                    #include <windows.h>
                    #
                    #include <malloc.h>
                    #include <string.h>
                    #include <stdio.h>
                     
                    int append(char **dst, const char *src)
                    {
                      size_t srcLen = strlen( src),
                             dstLen = strlen(*dst);
                      char  *newDst =realloc(*dst, dstLen + srcLen + 1);
                     
                      if (newDst == NULL) return 0;
                     
                      *dst = newDst;
                      strcat(*dst, src)[dstLen + srcLen] = ' ';
                      (*dst)[dstLen + srcLen + 1] = '\0';
                     
                      return 1;
                    }
                     
                    int main(int argn, char *argv[])
                    {
                      PROCESS_INFORMATION procInfo = { NULL };
                      STARTUPINFO         startInfo= { sizeof(startInfo), NULL, NULL, NULL, 0, 0, 0, 0, 0, 0,
                                                        0, STARTF_FORCEOFFFEEDBACK, 0, 0, NULL,
                                                        NULL, NULL, NULL};
                      char *cmdLine = calloc(1, 1);
                      int   res     = 1,
                            i;
                     
                      if (cmdLine == NULL)
                      {
                        printf("Insufficient memory\n");
                        goto cleanup;
                      }
                     
                      for (i = 1; i < argn; ++i)
                        if (!append(&cmdLine, argv[i]))
                        {
                          printf("Insufficient memory\n");
                          goto cleanup;
                        }
                     
                      if (cmdLine[0] == '\0')
                      {
                        printf("App for run is absent\n");
                        goto cleanup;
                      }
                      cmdLine[strlen(cmdLine)-1] = '\0';
                     
                      LARGE_INTEGER start, now, freq;
                     
                      if (QueryPerformanceFrequency(&freq) == 0)
                      {
                        printf("Time service is unavailable. Error code is %u\n", GetLastError());
                        goto cleanup;
                      }
                     
                      if (QueryPerformanceCounter(&start) == 0)
                      {
                        printf("Fault of time service request for start. Error code is %u\n", GetLastError());
                        goto cleanup;
                      }
                     
                      if (CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL,
                                        &startInfo, &procInfo) == 0)
                      {
                        printf("Error of %s launch. Error code is %u\n", argv[1], GetLastError());
                        goto cleanup;
                      }
                      CloseHandle(procInfo.hThread);
                      WaitForSingleObject(procInfo.hProcess, INFINITE);
                     
                      if (QueryPerformanceCounter(&now) == 0)
                      {
                        printf("Fault of time service request for finish. Error code is %u\n", GetLastError());
                        goto cleanup;
                      }
                     
                      printf("Time of run is %llu ms\n", (now.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);
                      res = 0;
                     
                    cleanup:
                      if (cmdLine != NULL) free(cmdLine);
                      if (procInfo.hProcess != NULL) CloseHandle(procInfo.hProcess);
                     
                      return res;
                    }

                  Для 3-х кб нужно выключить стандартные библиотеки и юзать только WinAPI. Последний вариант несложно адаптировать, просто умножаем время и отладку ещё на два. P.S. wsptintf() не умеет вывод long long.
                  WinAPI, поиск сырцов в crt\srс\i386 и "портирование" за полчаса, четыре сеанса отладки, размер образа от Студии 3,5к

                  ExpandedWrap disabled
                    #include <windows.h>
                    #
                    #include <stdarg.h>
                     
                    #define OUT_BUFFER_SIZE 1024
                     
                    int wprintf(LPCTSTR fmt, ...)
                    {
                      char    out[OUT_BUFFER_SIZE];
                      va_list args;
                      int     written;
                     
                      va_start(args, fmt);
                      written = wvsprintf(out, fmt, args);
                      va_end(args);
                      WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), out, written, &written, NULL);
                     
                      return written;
                    }
                     
                    const char *getCmdLine(const char *cmd)
                    {
                      if (*cmd == '"') while(*++cmd != '"') ;
                      while (*cmd != ' ') ++cmd;
                      while (*cmd == ' ') ++cmd;
                     
                      return cmd;
                    }
                     
                    int entryPoint(void)
                    {
                      PROCESS_INFORMATION procInfo = { NULL };
                      STARTUPINFO         startInfo= { sizeof(startInfo), NULL, NULL, NULL, 0, 0, 0, 0, 0, 0,
                                                        0, STARTF_FORCEOFFFEEDBACK, 0, 0, NULL,
                                                        NULL, NULL, NULL};
                      const char *commandLine = getCmdLine(GetCommandLine());
                            int   res         = 1,
                                  i;
                            char *cmdLine;
                     
                      if (*commandLine == '\0')
                      {
                        wprintf("App for run is absent\n");
                        goto cleanup;
                      }
                      cmdLine = HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, lstrlen(commandLine)+1);
                      if (cmdLine == NULL)
                      {
                        wprintf("App for run is absent\n");
                        goto cleanup;
                      }
                      lstrcpy(cmdLine, commandLine);
                     
                      LARGE_INTEGER start, now, freq;
                     
                      if (QueryPerformanceFrequency(&freq) == 0)
                      {
                        wprintf("Time service is unavailable. Error code is %u\n", GetLastError());
                        goto cleanup;
                      }
                     
                      if (QueryPerformanceCounter(&start) == 0)
                      {
                        wprintf("Fault of time service request for start. Error code is %u\n", GetLastError());
                        goto cleanup;
                      }
                     
                      if (CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL,
                                        &startInfo, &procInfo) == 0)
                      {
                        wprintf("Error of %hs launch. Error code is %u\n", cmdLine, GetLastError());
                        goto cleanup;
                      }
                      CloseHandle(procInfo.hThread);
                      WaitForSingleObject(procInfo.hProcess, INFINITE);
                     
                      if (QueryPerformanceCounter(&now) == 0)
                      {
                        wprintf("Fault of time service request for finish. Error code is %u\n", GetLastError());
                        goto cleanup;
                      }
                     
                      wprintf("Time of run is %lu ms\n", (unsigned long)((now.QuadPart - start.QuadPart) * 1000 / freq.QuadPart));
                      res = 0;
                     
                    cleanup:
                      if (cmdLine != NULL) HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, cmdLine);
                      if (procInfo.hProcess != NULL) CloseHandle(procInfo.hProcess);
                     
                      return res;
                    }

                  Строки для компиляции и линковки:
                  ExpandedWrap disabled
                    ml -c lldiv.asm llmul.asm
                    cl -O1 -GL -Zl -GS- сырец.c lldiv.obj llmul.obj user32.lib kernel32.lib -link /NODEFAULTLIB /ENTRY:entryPoint /SUBSYSTEM:CONSOLE
                  Оно того точно стоило?
                  Цитата JoeUser @
                  Ассемблер интересен.
                  Это совсем другой вопрос. P.S. Последний сырец к услугам.
                  Сообщение отредактировано: Qraizer -
                    Qraizer, а почему system_clock, а не high_resolution_clock?
                      Та без разницы. Миллисекунды же. Если миллисекунд вдруг мало, то да.
                        Цитата Qraizer @
                        Оно того точно стоило?

                        Да! Вот это красиво, если оно так (пока не проверил)!!! И утиль полезный, и реализация на достойном уровне. Пасип!
                        ЗЫ: Но с с асмом я всеж позже разберусь - хотелось увидеть куски кода для этих под-задач. Наверняка они привычны и злободневны :lol: для асм-писателей.
                          Qraizer, кстати ... а ты когда-нить смотрел в сторону lcc?
                          Описалово и линки, дистр x32, дистр x64, есличо.

                          Добавлено
                          Цитата Jin X @
                          Т.е. читаем QueryPerformanceCounter до запуска, QueryPerformanceCounter после запуска, считаем разницу и делим на QueryPerformanceFrequency, получаем секунды.

                          Ну пока, "на коленке", я вот такое намутил:
                          ExpandedWrap disabled
                            @echo off
                            SET RUN="ffmpeg -f rawvideo -pix_fmt yuv420p -s:v 1152x864 -r 25 -i out.yuv -i out.mp3 -c:v libx265 -preset veryfast -c:a libvorbis -shortest res.mkv"
                            PowerShell -NoProfile -ExecutionPolicy Bypass Measure-Command {%RUN%} > test-1-res.txt

                          Но нормальную утилиту time я уже вчера хочу! :)

                          Добавлено
                          Цитата JoeUser @
                          Qraizer, кстати ... а ты когда-нить смотрел в сторону lcc?

                          И еще вот это ... что скажешь с точки зрения С++ профи? :-? Сорри за оффтоп - просто уж больно интересная шляпа!!!!! Очень хочется с "иглы Qt" соскочить :'(

                          Добавлено
                          Скрытый текст
                          Цитата Qraizer @
                          Оно того точно стоило?

                          И есчо !!! Если приаттачить lldiv.asm llmul.asm, то твои труды неплохо было бы в FAQ C++ выложить. Мыже исходники, или где?! :angry:
                            Цитата Qraizer @
                            Та без разницы. Миллисекунды же. Если миллисекунд вдруг мало, то да.
                            Так, человек же даже в заголовке написал: "[Т]аймер высокого разрешения" :)
                              А чем миллисекунды не высокое, Jin X? Цифры не указаны, и я выбрал миллисекунды из практических соображений вокруг формулировки задачи. Ну и если придираться, нужно ещё убедиться, что QueryPerformanceFrequency() вернёт подходящие цифры. Впрочем, и решить задачу задачи не ставил, иначе на ассме б выложил. А так помог, на сколько было не жалко времени, перевести последний вариант на асм – вопрос желания, а не усилий.
                              Нет, не смотрел, JoeUser. На что там стоит смотреть? Ну компилятор и компилятор, чем он примечателен, чтоб на него обратить внимание? Ну, кроме лицензии, которую нынче и VS покрывает. За nano слышал, хвалили, не юзал.
                              Цитата JoeUser @
                              Если приаттачить lldiv.asm llmul.asm, то твои труды неплохо было бы в FAQ C++ выложить.
                              Это стандартные файлики из поставки сырцов RTL в VS. Компилятор их использует для умножения и деления 64-битных целых. Так-то они лежат в либах, но т.к. те отключены, нужно подкинуть свою реализацию. Мне было лень, я компильнул оригиналы. И нужны они только для 32-битного кода, в 64-х битах компилятор сам справляется с 64-битной арифметкой.
                                Цитата Qraizer @
                                и я выбрал миллисекунды из практических соображений вокруг формулировки задачи
                                Вообще, я согласен, что при запуске внешней проги, считать точнее, чем в миллисекундах, нет особого смысла.

                                Цитата Jin X @
                                не знаю, насколько такой таймер реально оправдан, ведь на запуск тоже уйдёт какое-то время и внесёт свою погрешность, так что, может, GetTickCount достаточно?
                                Это про микро/наносекунды.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0531 ]   [ 16 queries used ]   [ Generated: 25.06.21, 10:18 GMT ]