Ну это примерно как с новым (хотя тут и не совсем новый) языком программирования. Даже мне пришлось вспоминать - как писать - по прошествии лет так двадцати. Хотя в плане читабельности и понимабельности - никаких проблем - структурные операторы и уменьшение количества меток-операторов перехода - делают своё дело
И код, который опять периодически пописываю под УК-НЦ - КВАНТ (а скоро и под БК-0011М) - использует эти макросы - не так уж много времени на хобби, а тут реальное ускорение
Я давно (еще во времена работы с 51-м микроконтроллером) написал простенький препроцессор ассемблерных файлов, в котором решил проблему со структурностью и локальными метками ассемблера. В последствии оказалось что этот препроцессор подошел ко всем архитектурам (ассемблерам) с которыми мне приходилось и приходится работать с минимальными модификациями (а чаще вообще без модификаций).
Суть в том, что в место меток я использую конструкции вида:
Вместо 1 могут быть любые цифры, обозначающие на сколько уровней/шагов) нужно переходить.Код:----------------------------------------------- { br !o1 ; Выйти на один уровень вверх } ; т.е. сюда ----------------------------------------------- ; т.е. сюда { br !o1p1 ; Выйти на один уровень вверх и на один шаг назад } ----------------------------------------------- { br !o1n1 ; Выйти на один уровень вверх и на один шаг вперед } { ; Тут может быть любой код } ; т.е. сюда ----------------------------------------------- br !n1 ; На один шаг вперед { ; Тут может быть любой код } ; т.е. сюда ----------------------------------------------- ; т.е. сюда { ; Тут может быть любой код } br !p1 ; На один шаг назад -----------------------------------------------
Препроцессор сам расставляет локальные метки, комментирует фигурные скобки и заменяет конструкции типа !o1, !p1, !n1, !o1p1, !o1n1 на локальные метки, которые он расставил.
Я, если пишу на асме, то только с этим препроцессором. Код и пишется и читается на много легче.
Пример кода:
Если интересно, могу кинуть исходники препроцессора.Код:FEvent_Wait_For_Proc: { cmp #16,Y0 bhs !n1 { move #$8000,Y1 lsrr Y1,Y0,Y1 push_first Y1 lea (R2+2) push_last R2 { dis_int move X:(R2),Y0 and Y1,Y0 bne !n1 { jsr FDeActivate_Cur_Proc ena_int jsr FSwitch_From_Cur_Proc_L_H move X:(SP-1),Y1 move X:(SP),R2 jmp !o2p1 } } pop R2 pop Y1 rti } { cmp #32,Y0 IF DEBUG blo !n1 { dis_int { debug bra !o1p1 } } ELSE bhs !o1 ENDIF sub #16,Y0 move #$8000,Y1 lsrr Y1,Y0,Y1 push_first Y1 lea (R2+3) push_last R2 { dis_int move X:(R2),Y0 and Y1,Y0 bne !n1 { jsr DeActivate_Cur_Proc ena_int jsr Switch_From_Cur_Proc_L_H move X:(SP-1),Y1 move X:(SP),R2 jmp !o2p1 } } pop R2 pop Y1 } rti }
В том то и суть, что в моем примере - это все тот же ассемблер со всеми его инструкциями перехода, но все же появляется некоторая структурность кода и не нужно проставлять метки и придумывать им имена. Так же за счет структурности (в том числе и визуальной) намного проще найти куда указывает переход, чем искать в коде метку с нужным названием.
Так же плюсом того что нет привязки к конкретным инструкциям (мнемонике) является то, что этот препроцессор можно с легкостью использовать для разных архитектур.
В общем я никому ничего не навязываю, просто делюсь собственным опытом
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
Что касается !o3 то найти не проблема если каждый уровень вложенности сдвигать на определенное число пробелов.
Что касается !n5 и !p5 то на практике такие конструкции вряд ли будут использоваться. В основном !n1 !p1, реже !n2 !p2, ну и совсем редко !n3 !p3.
Если нужно перепрыгнуть (обойти) несколько (скажем 5) инструкций, то эти 5 инструкций выделяются фигурными скобками в отдельный блок, который уже будет обходится как !n1
Пример конструкции if () {} else {}:
Пример циклов:Код:tst R0 bne !n1 ; if (R0 == 0) { mov R1,(R4)+ mov R2,(R4)+ mov R3,(R4)+ br !o1n1 } ; else { mov R1,(R0)+ mov R2,(R0)+ mov R3,(R0)+ }
Извиняюсь если с мнемоникой чего напутал, давно под DEC ничего не писал.Код:mov R0,#40000 clr R1 mov R2,#20000 { ; do mov R1,(R0)+ sob R2,!o1p1 } ; while (R2)
Последний раз редактировалось konst_st; 12.10.2018 в 20:43.
И сравните с
- - - Добавлено - - -Код:if R0 eq #0 then ; будет TST, а не CMP mov R1,(R0)+ mov R2,(R0)+ mov R3,(R0)+ else mov R1,(R4)+ mov R2,(R4)+ mov R3,(R4)+ end
И да, безусловно, привычные вещи - привычней
Добавили в компилятор PDPy11 команды MUL, DIV, ASH, ASHC. Плагин подсветки синтаксиса в Sublime Text обновили соответственно.
Двоичные числа теперь можно записывать в виде #B1101001101111010.
Также напомню, что для удобства введены команды PUSH и POP (заменяют MOV что-нибудь,-(SP) и MOV (SP)+,куда-нибудь).
Последний раз редактировалось Manwe; 20.10.2018 в 17:49.
manwe.pdp-11.ru
А как вы отличаете метку B1101 от двоичного числа 1101 ? По количеству нулей и единиц, идущих за префиксом B ? Или теперь просто запрещено делать метки, начинающиеся с буквы B и содержащие только цифры 0 и 1 ? Или адресация #МЕТКА просто не используется в ассемблере ?
Использовали бы синтаксис префиксов, принятый в MACRO-11:
^B - префикс двоичного числа
^C - префикс инвертирования выражения, следующего за префиксом
^D - префикс десятичного числа (почти не используется, т.к. используется суффиксная запись с точкой на конце числа)
^F - префикс плавающего числа
^O - префикс восьмеричного числа (тривиальный вариант, нужен на тот случай, когда директивами задана принудительная интерпретация по умолчанию чисел в десятичной системе)
Ну и можно расширить:
^H или ^X - префикс 16ричного числа
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)