Ассемблерные головоломки или может ли машина понимать естественный язык

         

двух и трех байтовые команды второй группы


Смотрите! В первую группу попали все заглавные английские буквы, немного строчечный и значительная часть знаков препинания. То есть, закодировать можно практически все, что угодно, только бери и пиши! Компьютер не выбросит исключения и наш код будет вполне успешно исполнен. Правда, восклицательного знака здесь нет. А как же "HELLO,WORLD!". Ведь без восклицательного знака оно будет ущербным, если не сказать неполноценным. Во второй группе команд ничего подобного тоже не наблюдается. Все они начинаются с "посторонних" знаков и даже если передать восклицательный знак как непосредственное значение, получится полная ахинея. Например, AND AL,21h ("$!") или CMP AL,21h ("<!"). Выглядит отвратно. На самом деле, команда с опкодом 21h все-таки есть. Это, как подсказывает Матрица, AND r/m,r16. Правда, здесь возникает побочный эффект — обращение к памяти, поэтому приходится подбивать такую регистровую пару, которая бы не вызывала исключений, например, AND [SI],SP (21h 24h или "!$") в текстовом представлении. Только надо следить, чтобы SI указывал на память, не содержащую ничего интересного, иначе последствия себя не заставят ждать.

Кстати говоря, символ "$" нам очень пригодится, поскольку он служит завершителем MS-DOS строк. Это существенно отличает его от языка Си, в котором признаком конца строки является символ нуля.

Давайте для разминки наберем в hex-редакторе строку "HELLO,WORLD!$" и попробуем ее дизассемблировать:

00000000: 48                           dec       ax    ; уменьшить регистр ax на единицу

00000001: 45                           inc       bp    ; увеличить регистр bp на единицу

00000002: 4C                           dec       sp    ; уменьшить регистр sp

на единицу

00000003: 4C                           dec       sp    ; уменьшить регистр sp

на единицу

00000004: 4F                           dec       di    ; уменьшить регистр di

на единицу

00000005: 2C

57                        sub       al,057 ; отнять от регистра al

57h

00000007: 4F                           dec       di    ; уменьшить регистр di

на единицу

00000008: 52                           push      dx    ; затолкать в стек регистр dx

00000009: 4C                           dec       sp    ; уменьшить регистр sp

на единицу

0000000A: 44                           inc       sp    ; увеличить регистр sp

на единицу

0000000B: 2124                         and       [si],sp ; *si = sp



Содержание раздела