СОВРЕМЕННАЯ ЭЛЕКТРОНИКА №4/2012
Сброс линии TxD 1 79 00000140 EE out dx,al ; зап рет передачи. 1 80 00000141 B2 FD mov dl,0fdh ; Итого: dx=3fdh 1 81 00000143 EC in al,dx ; Пpовеpка факта 1 82 00000144 A8 01 test al,01h ; пpихода 1 83 00000146 74 FB jz $ 3 ; бай та. 1 84 00000148 B2 F8 mov dl,0f8h ; Итого: dx=3f8h 1 85 0000014A EC in al,dx ; Ввод байта из поpта данных (3f8h) в al. Теперь просмотрим файл p86rd каким либо файловым менеджером (Frigate, NortonCommander, Total Com mander и т.п.) в HEX формате: 00000000: 66 55 66 8B EC 06 1E 66|67 C4 7E 06 66 67 8B 16 | 00000010: 00 00 8E DA 66 26 67 8B|75 02 66 26 67 8B 0D 66 | 00000020: 81 E1 FF 7F B6 03 B2 FE|EC B2 FB B0 47 EE B2 FE | 00000030: EC A8 02 74 FB 33 C9 B1|14 EC E2 FD B2 FB B0 07 00000040: EE B2 FD EC A8 01 74 FB|B2 F8 EC 67 88 04 66 46 | 00000050: E2 D2 1F 07 66 5D | | Видно, чтовподпрограммеp86rd.com присутствует кодовая последователь ность (выделена шрифтом), которая в точности совпадает с кодами выделен ных операций в файле листинге. Эта кодовая последовательность и пред ставляет собой необходимые коды для вставки в подпрограмму на C++ Inbasm.cpp. Если теперь текстовым ре дактором убрать весь текст слева от вы деленного в файле листинге, снабдить каждый код операции символом «0x» и запятыми, а текст справа от выделен ного отделить знаками комментариев «//», то мыполучим код подключаемой подпрограммы для Inbasm.cpp. Фрагментфайла листинга P86WR.LST (подпрограмма p86wr.asm) и сама под программа p86wr.com в HEX формате приведены на сайте журнала. В подпрограмме p86wr.com кодовая последовательность, соответствующая кодовой последовательности в файле листинге, встречается трираза (выделе но). Поскольку вывод байта (OUTBYTE) является макросом, а не подпрограм мой, первые два обращения к этому макросу соответствуют выводу млад шего и старшего байтов длины стро ки, а третье – выводу самой строки. Кодовая последовательность файла листинга и является подключаемой вставкой в подпрограмму Outbasm.cpp. Программа, написаннаяна языкеCla rionсподключаемымивставками, пред назначена для работы вWindows XP, т.е. в 32 разрядномрежиме, апрограммана TB – для DOS, т.е. для 16 разрядного ре жима. Кодынекоторыхоперацийв16 и 32 разрядном режимах могут разли чатьсямежду собой. Кроме того, кодовая последовательность в файле листинге (точнее, порядок следования байт) так же может отличаться от соответствую щей ей кодовой последовательности в оттранслированномфайле в *.com фор мате (т.е. от объектных кодов). Для иллюстрации рассмотрим прос тейшуюпроцедуру ввода байта из пор та компьютера: загрузим адрес порта ввода (например, 3feh) в регистр dx процессора, затем дадим команду вво да из этого порта в младший байт акку мулятора аl: mov dx,03feh in al,dx Рассмотрим команду mov dx,03feh. Ниже приведены два варианта транс ляции этой команды: первый – в 16 разрядном режиме, когда параметр «.386» закомментирован, второй – в 32 разрядном режиме: ;.386 BA 03 FE mov dx,03feh – в файле листинге BA FE 03 – в файле *.com – форма та .386 66 BA 03 FE mov dx,03feh – в фай ле листинге 66 BA FE 03 – в файле *.com фор мата Видно, что коды операций в 16 и 32 разрядномрежиме различаются между собой (в 32 разрядном режиме транс лятор вставил дополнительный код 66h – префикс размера операнда, ука зывающий, что это edx, а не dx, и что адрес также 32 разрядный). Кроме то го, порядок следования байт кодов опе раций в файле листинге и в файле в *.com формате в каждом из режимов также отличается. Разумеется, в этом случае кодыфайла листинга для встав ки использовать нельзя. С другой стороны, загрузить число 03feh в регистр dx можно иначе: внача ле загрузить старший байт числа 03feh (03) в старшийбайт регистраdx (эторе гистрdh), а вмладшийбайт dl загрузить младший байт числа 03feh (0feh). Ниже приведёнвариант такой загрузки, кото рый даёт одинаковые коды в 16 и 32 разрядном режимах, и кроме того, ко ды файла листинга полностью совпа дают с кодами файла в *.com формате. .386/;.386 B6 03 mov dh,03h ; Итого: B2 FE mov dl,0feh; dx=3feh – в файле листинге B6 03 B2 FE – в файле *.com – формата Таким свойством обладают коды операций, длина которых не превы шает двух байт. Кстати, если для вво да/вывода используется порт COM1, у которого старший адрес (dh) равен 03h, то, загрузив однажды по этому адресу число 03h, для дальнейшего вво да/вывода с порта COM1 достаточно изменять только младший байт dl. По этому необходимо программу соста вить так, чтобы в ней использовались двухбайтовые команды. Вторым важныммоментом является правильное использование оператора цикла loop. Этот оператор работает аналогично операторам цикла Бейси ка: for … next, C++: for (…) {…}, Clarionа: loop … end. При использовании оператора loop, в счётчик циклов – регистр cx (ecx – в 32 разрядном режиме) – необходимо загрузить их число. Ниже приведены два варианта загрузки числа 20 в счёт чик циклов в 32 разрядном и 16 раз рядном режимах и показаны кодовые последовательности в файлах листин гах и в объектных кодах файлов в *.com формате. .386 B9 00 00 00 14 mov ecx,20 – в файле листинге B9 14 00 00 00 – в файле *.com – формата ;.386 B9 00 14 mov cx,20 – в файле лис тинге B9 14 00 – в файле *.com – форма та Видно, что коды операций в 16 и 32 разрядном режиме различаются ПРОГРАММИРОВАНИЕ 72 WWW.SOEL.RU СОВРЕМЕННАЯ ЭЛЕКТРОНИКА ◆ № 4 2012 © СТА-ПРЕСС
RkJQdWJsaXNoZXIy MTQ4NjUy