Да, это хорошо. Только скорость чтения получившегося кода сторонним программистом упала :) Я вот с ходу не въехал. А обычные БК-шные исходники из Turbo8 без проблем читаю.
Вид для печати
Ну это примерно как с новым (хотя тут и не совсем новый) языком программирования. Даже мне пришлось вспоминать - как писать - по прошествии лет так двадцати. Хотя в плане читабельности и понимабельности - никаких проблем - структурные операторы и уменьшение количества меток-операторов перехода - делают своё дело :)
И код, который опять периодически пописываю под УК-НЦ - КВАНТ (а скоро и под БК-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
}
В том то и суть, что в моем примере - это все тот же ассемблер со всеми его инструкциями перехода, но все же появляется некоторая структурность кода и не нужно проставлять метки и придумывать им имена. Так же за счет структурности (в том числе и визуальной) намного проще найти куда указывает переход, чем искать в коде метку с нужным названием.
Так же плюсом того что нет привязки к конкретным инструкциям (мнемонике) является то, что этот препроцессор можно с легкостью использовать для разных архитектур.
В общем я никому ничего не навязываю, просто делюсь собственным опытом :)
Что касается !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)
И сравните с
- - - Добавлено - - -Код: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)+,куда-нибудь).
А как вы отличаете метку B1101 от двоичного числа 1101 ? По количеству нулей и единиц, идущих за префиксом B ? Или теперь просто запрещено делать метки, начинающиеся с буквы B и содержащие только цифры 0 и 1 ? Или адресация #МЕТКА просто не используется в ассемблере ?
Использовали бы синтаксис префиксов, принятый в MACRO-11:
^B - префикс двоичного числа
^C - префикс инвертирования выражения, следующего за префиксом
^D - префикс десятичного числа (почти не используется, т.к. используется суффиксная запись с точкой на конце числа)
^F - префикс плавающего числа
^O - префикс восьмеричного числа (тривиальный вариант, нужен на тот случай, когда директивами задана принудительная интерпретация по умолчанию чисел в десятичной системе)
Ну и можно расширить:
^H или ^X - префикс 16ричного числа