Шаг 23.
Консольные приложения. Общие понятия

    На этом шаге мы рассмотрим общие принципы создания консольных приложений.

    Консольное приложение - приложение, выполняемое из коммандной строки, например из коммандной строки Far. Часто нет необходимости и времени для создания графического интерфейса, а программа должна что-то делать, например, обрабатывать большие объемы информации. И вот тут на помощь приходят консольные приложения. Ниже вы увидите, что консольные приложения очень компактны не только в откомпилированном виде, но и в текстовом варианте. Но главное, консольное приложение имеет такие же возможности обращаться к ресурсам Windows посредством API-функций, как и обычное графическое приложение.

    Приведем параметры для создания консольных приложений:

    Как и раньше, мы предполагаем, что библиотеки будут указываться при помощи директивы includelib. Ниже представлено простое консольное приложение для MASM и TASM соответственно. Для вывода текстовой информации используется функция API WriteConsoleA, параметры которой (слева направо) имеют следующий смысл:

    Заметим, что буфер, где находится выводимый текст, не обязательно должен заканчиваться нулем, поскольку для данной функции указывается количество выводимых символов. Договоримся только не путать входные/выходные буферы консоли и буферы, которые мы создаем в программе, в том числе и для обмена с буферами консоли.


    Пример 1. Простое консольное приложение для MASM32.
.386P
;Плоская модель памяти.
.MODEL FLAT, STDCALL
;Константы.
STD_OUTPUT_HANDLE   equ -11
;Прототипы внешних процедур.
EXTERN GetStdHandle@4:NEAR
EXTERN WriteConsoleA@20:NEAR
EXTERN ExitProcess@4:NEAR
;Директивы компоновщику для подключения библиотек.
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
;Сегмент данных.
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
;Строка в DOS-овской кодировке.
        STR1 DB "Консольное приложение",0
        LENS DD ? ;Количество выведенных символов.
        RES  DD ? 
_DATA ENDS 
;Сегмент кода.
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE' 
START: 
;Получить HANDLE вывода.
      PUSH STD_OUTPUT_HANDLE
      CALL GetStdHandle@4
;Длина строки.
      PUSH OFFSET  STR1
      CALL LENSTR 
;Вывести строку.
      PUSH OFFSET RES    ;Резерв.
      PUSH OFFSET LENS   ;Выведено символов.
      PUSH EBX           ;Длина строки.
      PUSH OFFSET STR1   ;Адрес строки.
      PUSH EAX           ;HANDLE вывода.
      CALL WriteConsoleA@20
      PUSH 0
      CALL ExitProcess@4 
;Строка -   [EBP+08H].
;Длина в ЕВХ 
LENSTR PROC
      PUSH  EBP
      MOV   EBP,ESP
      PUSH  EAX
;----------------------
      CLD
      MOV   EDI,DWORD PTR  [EBP+08H]
      MOV   EBX,EDI
      MOV   ECX,100 ;Ограничить длину строки.
      XOR   AL,AL
      REPNE SCASB   ;Найти символ 0.
      SUB   EDI,EBX ;Длина строки, включая 0.
      MOV   EBX,EDI
      DEC   EBX
;----------------------
      POP   EAX 
      POP   EBP 
      RET   4
LENSTR ENDP
_TEXT  ENDS
       END START
Текст этой программы можно взять здесь.


    Пример 2. Простое консольное приложение для TASM32.
.386P
;Плоская модель памяти.
.MODEL FLAT, STDCALL
;Константы.
STD_OUTPUT_HANDLE   equ -11
;Прототипы внешних процедур.
EXTERN GetStdHandle:NEAR
EXTERN WriteConsoleA:NEAR
EXTERN ExitProcess:NEAR
;Директивы компоновщику для подключения библиотек.
includelib c:\tasm32\lib\import32.lib
;Сегмент данных.
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
;Строка в DOS-овской кодировке.
        STR1 DB "Консольное приложение",0
        LENS DD ? ;Количество выведенных символов.
        RES  DD ? 
_DATA ENDS 
;Сегмент кода.
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE' 
START: 
;Получить HANDLE вывода.
      PUSH STD_OUTPUT_HANDLE
      CALL GetStdHandle
;Длина строки.
      PUSH OFFSET  STR1
      CALL LENSTR 
;Вывести строку.
      PUSH OFFSET RES    ;Резерв.
      PUSH OFFSET LENS   ;Выведено символов.
      PUSH EBX           ;Длина строки.
      PUSH OFFSET STR1   ;Адрес строки.
      PUSH EAX           ;HANDLE вывода.
      CALL WriteConsoleA
      PUSH 0
      CALL ExitProcess 
;Строка -   [EBP+08H].
;Длина в ЕВХ 
LENSTR PROC
      PUSH  EBP
      MOV   EBP,ESP
      PUSH  EAX
;----------------------
      CLD
      MOV   EDI,DWORD PTR  [EBP+08H]
      MOV   EBX,EDI
      MOV   ECX,100 ;Ограничить длину строки.
      XOR   AL,AL
      REPNE SCASB   ;Найти символ 0.
      SUB   EDI,EBX ;Длина строки, включая 0.
      MOV   EBX,EDI
      DEC   EBX
;----------------------
      POP   EAX 
      POP   EBP 
      RET   4
LENSTR ENDP
_TEXT  ENDS
       END START
Текст этой программы можно взять здесь.

    Надо сказать, что, поскольку информация выводится в консольном окне, кодировка всех строковых констант должна быть для DOS. В дальнейшем разъяснится вопрос, как осуществить перекодировку программным путем.

    Прокомментируем теперь приведенные выше программы. При запуске их из командной строки, например из программы Far, в строку выводится сообщение "Консольное приложение". При запуске программы как Windows-приложения консольное окно появляется лишь на секунду. В чем тут дело? Дело в том, что консольные приложения могут создать свою консоль. В этом случае весь ввод-вывод будет производиться в эту консоль. Если же приложение консоль не создает, то здесь может возникнуть двоякая ситуация: либо наследуется консоль, в которой программа была запущена, либо Windows создает для приложения свою консоль.

    На следующем шаге мы рассматрим вопросы, связанные с созданием консоли.




Предыдущий шаг Содержание Следующий шаг