Радио-86РК/Радио 12-91/Перемещаемые программы: различия между версиями
| Panther (обсуждение | вклад)  (http://retro.h1.ru/RK86/Programm/MovePrg.html) | Barsik (обсуждение | вклад)   (исправил опечатки и форматирование в исходнике) | ||
| Строка 1: | Строка 1: | ||
| {{ДИ|Автор= Е. ЕРЕМИН | Источник= http://retro.h1.ru/RK86/Programm/MovePrg.html}} | {{ДИ|Автор= Е. ЕРЕМИН | Источник= http://retro.h1.ru/RK86/Programm/MovePrg.html}} | ||
| С способность сохранять работоспособность при | С способность сохранять работоспособность при перемещении из одной области памяти в другую является важным достоинством программы, особенно если речь идет о системной программе. Обладающий этим свойством фрагмент может быть легко и без проблем включен в любое место любой программы, с минимальными усилиями переделан для работы на другом компьютере с той же системой команд процессора. | ||
| перемещении из одной области памяти в другую является важным достоинством программы, | |||
| особенно если речь идет о системной программе. Обладающий этим свойством фрагмент | |||
| может быть легко и без проблем включен в любое место любой программы, с минимальными | |||
| усилиями переделан для работы на другом компьютере с той же системой команд | |||
| процессора. | |||
| Для достижения перемещаемости используют различные | Для достижения перемещаемости используют различные приемы: размещают в определенной области памяти стандартную таблицу переходов, формируют специальную таблицу коррекции BITMAP , применяют особые процедуры модификации адресов в командах перехода. Можно, однако заранее позаботиться о перемещаемости разрабатываемой программы и получить в результате код мало | ||
| приемы: размещают в определенной области памяти стандартную таблицу переходов | |||
| , формируют специальную таблицу коррекции BITMAP , применяют особые процедуры | |||
| модификации адресов в командах перехода. Можно, однако заранее позаботиться | |||
| о перемещаемости разрабатываемой программы и получить в результате код мало | |||
| зависящий или, в идеальном случае, совсем не зависящий от места расположения | зависящий или, в идеальном случае, совсем не зависящий от места расположения | ||
| в памяти компьютера. Некоторые приемы, позволяющие достичь этого, описаны ниже. | в памяти компьютера. Некоторые приемы, позволяющие достичь этого, описаны ниже. | ||
| Предполагается, что читатель знаком с основными | Предполагается, что читатель знаком с основными принципами работы микропроцессора КР580ВМ80 и имеет перед собой таблицу с системой его команд. | ||
| принципами работы микропроцессора КР580ВМ80 и имеет перед собой таблицу с системой | |||
| его команд. | |||
| В качестве примера перемещаемой программы рассмотрим | В качестве примера перемещаемой программы рассмотрим фрагмент определяющий количество байт в машинной команде. Такая задача часто возникает в различного рода дизассемблирующих программах, и разработанная подпрограмма может представлять самостоятельный интерес. Исходный текст, размещение кодов в памяти и комментарии приведены. Отметим, что адреса команд приведены для удобства изложения, в рассматриваемой программе они не используются. | ||
| фрагмент определяющий количество байт в машинной команде. Такая задача часто | |||
| возникает в различного рода дизассемблирующих программах, и разработанная подпрограмма | |||
| может представлять самостоятельный интерес. Исходный текст, | |||
| размещение кодов в памяти и комментарии приведены. Отметим, что адреса команд | |||
| приведены для удобства изложения, в рассматриваемой программе они не используются. | |||
| <pre> | <pre> | ||
| Строка 31: | Строка 15: | ||
| ; ВХОД: HL - АДРЕС КОМАНДЫ | ; ВХОД: HL - АДРЕС КОМАНДЫ | ||
| ; ВЫХОД:В - ЧИСЛО БАЙТ В КОНАНДЕ (0-КОМАНДЫ НЕТ) | ; ВЫХОД:В - ЧИСЛО БАЙТ В КОНАНДЕ (0-КОМАНДЫ НЕТ) | ||
| ;	С - НАЛИЧИЕ АДРЕСА В КОНАНДЕ (0-НЕТ, 1-ДА) | ;       С - НАЛИЧИЕ АДРЕСА В КОНАНДЕ (0-НЕТ, 1-ДА) | ||
| ;	D - КОД КОНАНДЫ | ;       D - КОД КОНАНДЫ | ||
| ;  | ;       HL - СОХРАНЯЕТСЯ АДРЕС КОНАНДИ | ||
| ; ВЫЗОВ ПОДПРОГРАННЫ NB ПО ОТНОСИТЕЛЬНОНУ АДРЕСУ | ; ВЫЗОВ ПОДПРОГРАННЫ NB ПО ОТНОСИТЕЛЬНОНУ АДРЕСУ | ||
| 0120  | 0120                    ORG 120Н | ||
| 0120	110100  | 0120    110100          LXI D,1         ; СМЕЩЕНИЕ ДЛЯ АДРЕСА П/П | ||
| 0123  | 0123    CDZZZZ          CALL ХХХХ       ; ВЫЗОВ П/П (СМ. ПРИМЕЧАНИЕ) | ||
| 0126  | 0126    С9              RET | ||
| ; ПОДПРОГРАММА NB (КОЛИЧЕСТВО БАЙТ) | ; ПОДПРОГРАММА NB (КОЛИЧЕСТВО БАЙТ) | ||
| ; | ; | ||
| 0127  | 0127    010001          LXI В,100Н | ||
| 012А  | 012А    7Е              MOV А,Н         ; КОД КОНАНДЫ | ||
| 012В  | 012В    57              MOV D,A         ; СОХРАНИТЬ В D | ||
| 012С  | 012С    B7              ORA А | ||
| 012D  | 012D    С8              RZ              ; ВЫХОД ПРИ NOP (В=1, С=0) | ||
| 012Е  | 012Е    17              RAL             ; ПРОВЕРКА НА СОВПАДЕНИЕ | ||
| 012F  | 012F    17              RAL             ; ДВУХ СТАРШИХ БИТОВ | ||
| 0130  | 0130    89              ADC С           ;       7=>1,  6=>CY, | ||
| 0131  | 0131    E601            ANI 1           ;       1 БИТ+CY+0 (ИЗ РЕГ.С) | ||
| 0133  | 0133    C0              RNZ             ;       3F<КОД<С0 | ||
| 0134  | 0134    7А              MOV A.D | ||
| 0135  | 0135    E6E7            ANI 0E7H | ||
| 0137  | 0137    FE02            CPI 2 | ||
| 0139  | 0139    С8              RZ              ;       STAX И LDAX (B=1, C=0) | ||
| 013A  | 013A    7A              MOV A,D | ||
| 013В  | 013В    E6CF            ANI 0CFH | ||
| 013D  | 013D    FEC1            CPI 0C1H | ||
| 013F  | 013F    C8              RZ              ;       POP (B=1, C=0) | ||
| 0140  | 0140    0603            MVI B,3 | ||
| 0142  | 0142    FE01            CPI 1 | ||
| 0144  | 0144    С8              RZ              ;       LXI (B=3, C=0) | ||
| 0145  | 0145    0С              INR С | ||
| 0146  | 0146    7А              MOV A,D | ||
| 0147  | 0147    FEC3            CPI 0С3Н | ||
| 0149  | 0149    С8              RZ              ;       JMP (B=3, C=1) | ||
| 014A  | 014A    FECD            CPI 0CDH | ||
| 014C  | 014C    C8              RZ              ;       CALL (B=3, C=1) | ||
| 014D  | 014D    0D              DCR С | ||
| 014E  | 014E    41              MOV В,С | ||
| 014F  | 014F    E6CF            ANI 0CFH | ||
| 0151  | 0151    FECD            CPI 0CDH        ;       КОДЫ DD-FD (B=0, C=0) | ||
| 0153  | 0153    С8              RZ              ;       НЕТ КОМАНД | ||
| 0154  | 0154    04              INR В | ||
| 0155  | 0155    E607            ANI 7 | ||
| 0157  | 0157    FE05            CPI 5 | ||
| 0159  | 0159    С8              RZ              ;       DCR, DCX, PUSH (B=1, C=0) | ||
| 015A  | 015A    FE07            CPI 7 | ||
| 015C	C8  | 015C    C8              RZ              ;       RST, СДВИГ И Т.Д. (В=1, С=0) | ||
| 015D  | 015D    04              INR В | ||
| 015E  | 015E    FE06            CPI 6           ;       MVI, ADI, SUI, ORI | ||
| 0160  | 0160    C8              RZ              ;       и т.д. (B=2, C=0) | ||
| 0161  | 0161    04              INR В | ||
| 0162  | 0162    0С              INR С | ||
| 0163  | 0163    FE02            CPI 2           ;       УСЛОВНЫЕ ПЕРЕХОДЫ, SHLD. | ||
| 0165  | 0165    C8              RZ              ;       LHLD, STA, LDA (В=3, С=1) | ||
| 0166  | 0166    7А              MOV A,D | ||
| 0167  | 0167    Е6С7            ANI 0С7Н | ||
| 0169  | 0169    FEC4            CPI 0C4H        ;       УСЛОВНЫЙ ВЫЗОВ | ||
| 016В  | 016В    С8              RZ              ;       ПОДПРОГРАММЫ (В=З, С=1) | ||
| 016С  | 016С    0D              DCR С | ||
| 016D  | 016D    41              MOV В,С | ||
| 016Е  | 016Е    7A              MOV A,D | ||
| 016F  | 016F    Е6С7            ANI 0C7H        ;       КОДЫ 10-30, 08-З8 (В=0, С=0) | ||
| 0171  | 0171    С8              RZ              ;       НЕТ КОМАНД | ||
| 0172  | 0172    04              INR В | ||
| 0173  | 0173    FEC0            CPI 0C0H | ||
| 0175  | 0175    C8              RZ              ;       ВОЗВРАТ ПО УСЛОВИЯМ (В=1, С=0) | ||
| 0176  | 0176    7А              MOV A,D | ||
| 0177  | 0177    FE40            CPI 40H | ||
| 0179  | 0179    D8              RС              ;       КОД<40(В=1, С=0) | ||
| 017A  | 017A    FEE0            CPI 0Е0Н | ||
| 017C  | 017C    D8              RNС             ;       КОД>ВF (В=1, С=0) | ||
| 017D  | 017D    FEC9            CPI 0С9Н | ||
| 017F	С8  | 017F    С8              RZ              ;       RET (B=1, C=0) | ||
| 0180  | 0180    04              INR В | ||
| 0181  | 0181    E6F7            ANI 0F7H | ||
| 0183  | 0183    FED3            CPI 0D3H | ||
| 0105  | 0105    C8              RZ              ;       IH, OUT (B=2, C=0) | ||
| 0106  | 0106    41              MOV В,С         ;       КОДЫ D9, СВ (В=О, С=0) | ||
| 0187  | 0187    С9              RET             ;       НЕТ КОМАНД | ||
|         ; ПРИМЕЧАНИЕ : | |||
|         ; С АДРЕСА ZZZZ (МЕТКА ХХХХ) ПРЕДВАРИТЕЛЬНО | |||
|         ; ЗАНОСЯТСЯ СЛЕДУЮЩИЕ КОМАНДЫ: | |||
|         ; ZZZZ  ЕЗ ХХХХ:XTHL    ; ВЫЧИСЛЕНИЕ АБСОЛЮТООГО | |||
|         ;       EB      XCHG    ; АДРЕСА НАЧАЛА П/П | |||
|         ;       19      DAD D   ; (СМЕЩЕНИЕ ЗАДАНО В DE) | |||
|         ;       ЕВ      XCHG    ; С СОХРАНЕНИЕН РЕГИСГРА HL | |||
|         ;       ЕЗ      XTHL | |||
|         ;       D5      PUSH D  ; АДРЕС НАЧАЛА П/П В СТЕК | |||
|         ;       С9      RET     ; ПЕРЕХОД К ПОДПРОГРАММЕ | |||
| </pre> | </pre> | ||
Текущая версия от 08:06, 18 февраля 2020
|   | Данный материал защищён авторскими правами! Использование материала заявлено как добросовестное, исключительно для образовательных некоммерческих целей. Автор: Е. ЕРЕМИН | 
С способность сохранять работоспособность при перемещении из одной области памяти в другую является важным достоинством программы, особенно если речь идет о системной программе. Обладающий этим свойством фрагмент может быть легко и без проблем включен в любое место любой программы, с минимальными усилиями переделан для работы на другом компьютере с той же системой команд процессора.
Для достижения перемещаемости используют различные приемы: размещают в определенной области памяти стандартную таблицу переходов, формируют специальную таблицу коррекции BITMAP , применяют особые процедуры модификации адресов в командах перехода. Можно, однако заранее позаботиться о перемещаемости разрабатываемой программы и получить в результате код мало зависящий или, в идеальном случае, совсем не зависящий от места расположения в памяти компьютера. Некоторые приемы, позволяющие достичь этого, описаны ниже.
Предполагается, что читатель знаком с основными принципами работы микропроцессора КР580ВМ80 и имеет перед собой таблицу с системой его команд.
В качестве примера перемещаемой программы рассмотрим фрагмент определяющий количество байт в машинной команде. Такая задача часто возникает в различного рода дизассемблирующих программах, и разработанная подпрограмма может представлять самостоятельный интерес. Исходный текст, размещение кодов в памяти и комментарии приведены. Отметим, что адреса команд приведены для удобства изложения, в рассматриваемой программе они не используются.
; ПОДПРОГРАММА ОПРЕДЕЛЕНИЯ КОЛИЧЕСТВА БАЙТ В КОМАНДЕ
; ВХОД: HL - АДРЕС КОМАНДЫ
; ВЫХОД:В - ЧИСЛО БАЙТ В КОНАНДЕ (0-КОМАНДЫ НЕТ)
;       С - НАЛИЧИЕ АДРЕСА В КОНАНДЕ (0-НЕТ, 1-ДА)
;       D - КОД КОНАНДЫ
;       HL - СОХРАНЯЕТСЯ АДРЕС КОНАНДИ
; ВЫЗОВ ПОДПРОГРАННЫ NB ПО ОТНОСИТЕЛЬНОНУ АДРЕСУ
0120                    ORG 120Н
0120    110100          LXI D,1         ; СМЕЩЕНИЕ ДЛЯ АДРЕСА П/П
0123    CDZZZZ          CALL ХХХХ       ; ВЫЗОВ П/П (СМ. ПРИМЕЧАНИЕ)
0126    С9              RET
; ПОДПРОГРАММА NB (КОЛИЧЕСТВО БАЙТ)
;
0127    010001          LXI В,100Н
012А    7Е              MOV А,Н         ; КОД КОНАНДЫ
012В    57              MOV D,A         ; СОХРАНИТЬ В D
012С    B7              ORA А
012D    С8              RZ              ; ВЫХОД ПРИ NOP (В=1, С=0)
012Е    17              RAL             ; ПРОВЕРКА НА СОВПАДЕНИЕ
012F    17              RAL             ; ДВУХ СТАРШИХ БИТОВ
0130    89              ADC С           ;       7=>1,  6=>CY,
0131    E601            ANI 1           ;       1 БИТ+CY+0 (ИЗ РЕГ.С)
0133    C0              RNZ             ;       3F<КОД<С0
0134    7А              MOV A.D
0135    E6E7            ANI 0E7H
0137    FE02            CPI 2
0139    С8              RZ              ;       STAX И LDAX (B=1, C=0)
013A    7A              MOV A,D
013В    E6CF            ANI 0CFH
013D    FEC1            CPI 0C1H
013F    C8              RZ              ;       POP (B=1, C=0)
0140    0603            MVI B,3
0142    FE01            CPI 1
0144    С8              RZ              ;       LXI (B=3, C=0)
0145    0С              INR С
0146    7А              MOV A,D
0147    FEC3            CPI 0С3Н
0149    С8              RZ              ;       JMP (B=3, C=1)
014A    FECD            CPI 0CDH
014C    C8              RZ              ;       CALL (B=3, C=1)
014D    0D              DCR С
014E    41              MOV В,С
014F    E6CF            ANI 0CFH
0151    FECD            CPI 0CDH        ;       КОДЫ DD-FD (B=0, C=0)
0153    С8              RZ              ;       НЕТ КОМАНД
0154    04              INR В
0155    E607            ANI 7
0157    FE05            CPI 5
0159    С8              RZ              ;       DCR, DCX, PUSH (B=1, C=0)
015A    FE07            CPI 7
015C    C8              RZ              ;       RST, СДВИГ И Т.Д. (В=1, С=0)
015D    04              INR В
015E    FE06            CPI 6           ;       MVI, ADI, SUI, ORI
0160    C8              RZ              ;       и т.д. (B=2, C=0)
0161    04              INR В
0162    0С              INR С
0163    FE02            CPI 2           ;       УСЛОВНЫЕ ПЕРЕХОДЫ, SHLD.
0165    C8              RZ              ;       LHLD, STA, LDA (В=3, С=1)
0166    7А              MOV A,D
0167    Е6С7            ANI 0С7Н
0169    FEC4            CPI 0C4H        ;       УСЛОВНЫЙ ВЫЗОВ
016В    С8              RZ              ;       ПОДПРОГРАММЫ (В=З, С=1)
016С    0D              DCR С
016D    41              MOV В,С
016Е    7A              MOV A,D
016F    Е6С7            ANI 0C7H        ;       КОДЫ 10-30, 08-З8 (В=0, С=0)
0171    С8              RZ              ;       НЕТ КОМАНД
0172    04              INR В
0173    FEC0            CPI 0C0H
0175    C8              RZ              ;       ВОЗВРАТ ПО УСЛОВИЯМ (В=1, С=0)
0176    7А              MOV A,D
0177    FE40            CPI 40H
0179    D8              RС              ;       КОД<40(В=1, С=0)
017A    FEE0            CPI 0Е0Н
017C    D8              RNС             ;       КОД>ВF (В=1, С=0)
017D    FEC9            CPI 0С9Н
017F    С8              RZ              ;       RET (B=1, C=0)
0180    04              INR В
0181    E6F7            ANI 0F7H
0183    FED3            CPI 0D3H
0105    C8              RZ              ;       IH, OUT (B=2, C=0)
0106    41              MOV В,С         ;       КОДЫ D9, СВ (В=О, С=0)
0187    С9              RET             ;       НЕТ КОМАНД
        ; ПРИМЕЧАНИЕ :
        ; С АДРЕСА ZZZZ (МЕТКА ХХХХ) ПРЕДВАРИТЕЛЬНО
        ; ЗАНОСЯТСЯ СЛЕДУЮЩИЕ КОМАНДЫ:
        ; ZZZZ  ЕЗ ХХХХ:XTHL    ; ВЫЧИСЛЕНИЕ АБСОЛЮТООГО
        ;       EB      XCHG    ; АДРЕСА НАЧАЛА П/П
        ;       19      DAD D   ; (СМЕЩЕНИЕ ЗАДАНО В DE)
        ;       ЕВ      XCHG    ; С СОХРАНЕНИЕН РЕГИСГРА HL
        ;       ЕЗ      XTHL
        ;       D5      PUSH D  ; АДРЕС НАЧАЛА П/П В СТЕК
        ;       С9      RET     ; ПЕРЕХОД К ПОДПРОГРАММЕ
Описываемый фрагмент состоит из собственно подпрограммы определения количества байт в машинной команде, назовем ее NB, и обращения к ней. Обращение находится в адресах 120Н—126Н, а далее, начиная с адреса 127Н (хотя адрес и не имеет значения), расположена подпрограмма NB, с которой и начнем анализ.
Характерной чертой подпрограммы является полное отсутствие условных переходов, замененных из соображений перемещаемости возвратом по условию. Проверка в этом случае происходит в следующей последовательности: задаются выходные значения регистров В и С, соответствующие той или иной группе команд; выделяются характерные для этой группы биты; операциями ANI или СРI устанавливаются признаки и при выполнении необходимого условия происходит выход из подпрограммы. В противном случае анализ кода продолжается аналогичным образом.
Рассмотрим несколько примеров. Команда 127 заносит в ВС константу, соответствующую однобайтовой операции, и если в ОЗУ по адресу, записанному в регистре HL, находится NOP (код 0), то происходит выход из подпрограммы (адреса 12СН и 12DH). Затем выделяется вся средняя часть таблицы команд микропроцессора КР580ВМ80 (коды в диапазоне 40H—BFH), содержащая однобайтовые команды. Это сделать труднее, так как проверить сразу два условия по принятой методике нельзя. Внимательное изучение кодов команд показывает, однако, что можно обойтись и одной проверкой: при попадании в указанный диапазон два старших бита кода различны, а в противном случае они одинаковы (читатели могут убедиться в этом самостоятельно). Для сравнения старших битов производятся два циклических сдвига влево через бит переноса CY. При этом седьмой (старший) бит оказывается в нулевом бите аккумулятора, а шестой попадает в CY. По команде ADC С (адрес 130Н) интересующие нас биты складываются, и если они были различны, дают единицу (не забывайте, что в регистре С записан 0, и он не влияет на результат сложения). Если же при сложении в младшем бите получился 0, то анализ необходимо продолжить. Команды 134—139 «распознают» операции LDAX и STAX, в коде которых характерными битами являются три младших (с 0 по 2) и три старших (с 5 по 7). Трем младшим соответствует комбинация 010, а трем старшим — 000. Нетрудно убедиться, что после сброса битов 3 и 4 (команда 135) результат А-2 гарантирует, что мы имеем дело именно с этой группой команд.
Дальнейший анализ происходит аналогично. Следует только иметь в виду, что перед переходом к выявлению команды с другим количеством байт необходимо каждый раз предварительно изменять выходные параметры в регистрах В и С. Если коду не соответствует команда микропроцессора КР580ВМ80, то в регистровую пару ВС подпрограмма выдает 0.
Таким образом, мы убедились, что достаточно сложная в логическом отношении программа не содержит ни одного явно заданного адреса, а значит, полностью перемещаема. Как же к ней обратиться, если команда CALL требует задать абсолютный адрес подпрограммы? Один из возможных вариантов обращения использован в нашем примере (адреса 120Н—126Н). По пред полагаемому адресу рабочей области памяти (в таблице он заменен символами ZZZZ, ему соответствует метка Х XXX) должен быть предварительно занесен небольшой фрагмент приведенный в примечании таблице. При обращении к нему происходит вычисление абсолютного адреса начала подпрограммы по смещению заданному в регистровой паре DE (в нашем случае адрес определяется как 126+1=127).
Коды рассмотренной программы можно перемещать по памяти без единого изменения, при этом работоспособность программы полностью сохраняется. Требуется, правда, выделить 7 байтов в рабочей области, адреса которых заданы «жестко», но, представляется, это незначительная плата за полную перемещаемость программы (особенно удобно, если указанные 7 команд размещены в ПЗУ).
Автор желает успеха начинающим программистам и надеется, что описанные приемы разработки перемещаемых программ будут полезны владельцам «Радио-86РК», «Микроши» и других микрокомпьютеров на процессоре КР580ВМ80.
Е. ЕРЕМИН, г. Пермь.
Отсканировано с журнала Радио № 12 1991 г.
Отредактировано Лесных Ю.
