Наверх

След.  

Создание com-файла.

 

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

Покопавшись в статьях в интернете, я в конце концов составил представление о том, как устроен файл com. А он может быть устроен так.

С самого начала идут машинные команды. Последними выполняемыми командами могут быть

MOV 4c00h

INT 21h

Они заканчивают выполнение программы. Их машинный вид (как мы видим их в com-файле):

            B8 00 4C

            CD 21

Данные же можно поместить в конце. Например, сразу после последних исполняемых команд, приведенных выше.

Приведем фрагмент, где нам могут понадобиться данные. Это, для примера, вывод строки на экран. Строка должна заканчиваться знаком доллара (код 24h). Сам этот знак на экран не выводится.

Ассемблерные команды для вывода строки:

MOV ah,09h

MOV dx, OFFSET Mes

INT 21h

Что это за OFFSET и Mes? Mes это переменная. А OFFSET фактически означает, что нам нужно смещение этой переменной. Относительно чего? Сейчас разберемся.

Все заработает, если вместо OFFSET Mes мы подставим число, которое будет равно смещению наших данных, но не от начала файла, а от начала файла плюс 100h (то-есть плюс 256 в десятичной форме).

То-есть если данные начинаются с 12-го байта (нумерация с нуля), то команда будет иметь такой вид:

MOV ah,09h

MOV dx, 256+12

INT 21h

А в машинной форме:

B4 09

BA 0C 01

CD 21

Старший и младший байты смещения здесь поменяны местами (так нужно).

 

В связи со всем этим может оказаться полезной программка, которая создает com-файл из текстового файла. В каждой строке текстового файла байт машинной команды в шестнадцатиричной форме. Причем записано все так, как принято в языке C (с префиксом 0x).

Например, содержимое файла может быть таким:

0x90

0xB8

0x0

0x0

0x8B

0xD0

0x3B

0xC2

0x74

0xe6

0xB4

0x09

0xBA

0x3b

0x01

0xCD

0x21

0xB4

0x09

0xBA

0x42

0x01

0xCD

0x21

0xB8

0x0

0x4C

0xCD

0x21

0x30

0x31

0xD

0xA

0x24

0x30

0x31

0x31

0x31

0xD

0xA

0x24

0x30

0x30

0xD

0xA

0x24

 

Приведу текст программы на языке C (она воспримет команды из файла Pr.txt и создаст файл Prog.com):

 

    #include <stdio.h>

    #include <stdlib.h>

    #include "Str_ex.h"

    #include "QnS.h"

 

 

 

 

            char End[3];    /* Это конец строки в текстовом файле */

 

 

            /*******************/

 

 

 

    void main(void)

 

    {

                        int j=1;

                        int R;

                        long Res;

                        short iRes;

        FILE *f1;

 

                        End[0]=13;

                        End[1]=10;

                        End[2]=0;

                        char dest[200];

                        char D[10];

                        char *pD;

 

                        /*sprintf(dest,"%d",sizeof(short));

                        WrStr("Result.txt",End,dest,1);*/  /* Result=2*/

 

                        pD=&D[0];

 

        f1=fopen("Prog.com","wb");

        if(f1==NULL)

                        {

        return;

                        }

 

 

 

                        while(j>0)

                        {

                        R=FindStrN("Pr.txt",End,dest,100,j);

                        j++;

 

                        if(R<0)

                        {

                                    *dest=0;

            /*WrStr("Lexema.txt",End," THE END! ",1);*/

                                    break;

                        }

                        else

                        {

        /*WrStr("Lexema.txt",End,Lex,1);*/ /* В тестовых целях

                                                                                                               пишем в файл */

                                    Res=strtol(dest,NULL,0);

                                    iRes=(short)Res;

                                    pD=(char *)&iRes;

                                    fputc(*pD,f1);

                                    /*fputc(*(pD+1),f1);*/

                        };

                        }

        fclose(f1);

 

        return;

            }

Это программа из проекта в папке PrCom2 для Visual C++ 5.0 (Смотреть). Здесь используется функция FindStrN из моей библиотеке для чтения строки с определенным номером из текстового файла. «Скорострельность» данного алгоритма далеко не оптимальна, но здесь нам важен принцип. В дальнейшем я также часто буду использовать свои функции.

Итак, если мы каким-либо образом (например скомпилировав «вручную») узнали машинные коды интересующего нас DOSовского приложения и занесли их в файл Pr.txt, то с помощью вышеописанной программы мы получим исполняемый com-файл.

 

Хостинг от uCoz