Кaк правило, для обращения к внешним функциям служит функция вызова пользовательского кода через USR с «магическим» числом…. В частности, «TR-DOS» - «USR 15619», «MONITOR» - «USR 63247» и т.д… Главный недостаток «магических» чисел - сложность их запоминания на первых парах для новичка…
Здравствуйте!
Когда я попытался писать собственные подпрограммы на ассемблере, задался вопросом адресов их посадки, чтобы было легче запоминать. Что-то типа «USR 65432» или «USR 55555»…
С одной стороны, так делать можно. Однако, главный очевидный недостаток - слишком много цифр в этих числах, не говоря уж о том, что «RANDOMIZE USR», как ни крути, довольно громоздкое…
Так как я продолжительное время пользовался РЛК «РАДИО-86РК», Бейсик позволял там обращаться к функциям программы «МОНИТОР» относительно компактно - «USR(-2021)» или «USR(-2045)». Если визуально игнорировать «-20», то цифры «21» и «45» достаточно легко запомнить. Что-то типа «XXI век» и «Год Победы»…
К сожалению, в ZX отрицательные числа в качестве аргумента «USR» вызывают ошибку целого и не позволяют писать что-то типа «USR -3»…
И я решил найти «побочные» методы из-под «Spectrum-48»… А именно, я быстренько и бегло визуально пробежал по всем байтам «ROM 48» и отыскал все места, где комбинация байтов составляет прыжок на дальние адреса, хотя реально это - таблица токенов Бейсика или «сбитый» адрес подпрограммы…
Оказалось, что через короткое «RANDOMIZE USR 17» можно совершить прыжок на адрес $FF15, так как там «0011: F2 15 FF»… При этом, состояние флажков процессора способствует выполнению этой инструкции.
Затем, когда я увлёкся, ещё одно короткое нашлось «RANDOMIZE USR 178» с содержимым «00B2: D2 14 D4». Но тут всё гораздо интереснее…
Оказывается этой инструкции предшествуют целых 9 байт, которые существенно ничего не меняют. А именно «00A9: 53 43 52 45 4E A4 41 54 54»…
Тем самым, получается целый диапазон адресов, доступных через «RANDOMIZE USR 169…178»…
Учитывая, что в «BC» сохраняется сам адрес 169…178 для помещение в стек перед вызовом, то его можно прочитать, откатив указатель стека и выполнив «POP HL». Это позволит определить по содержимому регистра «L» конкретный адрес от «USR» и в наше распоряжение предоставляется 10 подфункций, вызываемых через «USR (169+n)», где «n» - целое от 0 до 9…
Думаю, это весьма неплохо иметь целых десять «магических» очень коротких номерков!
Таким образом, по вектору «$D414» может лежать наш пользовательский код с переходами на 10 отдельных подфункций…
А сама наша библиотека может похвастаться почти рекламным слоганом, типа «позвони мне на короткие номера от 169 до 178»…
Через некоторое время я собрал неплохую коллекцию всех этих «побочных номерков»…
Некоторые из них прыгают на экранную область, что тоже неплохо, если мы загружаем собственный логотип непосредственно на экран и прыгаем на этот же экран (красивый «USR 222» прыгнет на $5153»), что уже напоминает QR-код «по-Спектрумски»!
Вот здесь некоторые из векторов, которые я выявил:
Короткие USR-индексы
Кратко:
Более подробно:Код:Несколько адресочков: ========================= C409() USR 5555/5556 C53E USR 633/635/636 CB2D() USR 682 CCC8() USR 621 CD09() USR 2696 CD1F USR 8197/8215 CFA5 USR 651 E52B USR 11095 F430() USR 1432 F515() USR 3897 F51F USR 8709 F52A() USR 10860/10890 FD1F USR 8240 FE3E USR 1908 FF15 USR 11 ======================== Скобки () означают переход через CALL, а не JP. Потому, необходимо это учитывать и корректировать стек перед RET.
Развёрнуто:Код:Таблица коротких магических USR-чисел для вызова далёких подпрограмм. ===================================================================== ROM ADDRESS - шестнадцатиричный адрес в ПЗУ Бейсика 48K. USR VECTOR - десятичный индекс к использованию из USR. RAM TARGET - шестнадцатиричный целевой адрес памяти от JP (XXXX) шестнадцатиричный целевой адрес памяти от CALL (+XXXX) шестнадцатиричный байт-код предшествующей команды (XX) _______________________________________________________________________________________________ $0011 $026D $0279 $027B $027C $0287 $0289 $028B $02AA $0598 $0774 $0980 $0982 $0A88 $0B8F $0D9D - ROM ADDRESS 17 621 633 635 636 647 649 651 682 1432 1908 2432 2434 2696 2859 3485 - USR VECTOR FF15 +CCC8 22 3C C53E D4D3 +D2D5 CFA5 +CB2D +F430 FE3E EE +DD15 +CD09 +D10E +A709 - RAM TARGET _______________________________________________________________________________________________ $0E37 $0EB5 $0ED5 $0F39 $0F6D $101F $1022 $1162 $127B $15AF $15B3 $15B4 $18D5 $197F $1C95 $2005 - ROM ADDRESS 3639 3765 3797 3897 3949 4127 4130 4450 4731 5551 5555 5556 6357 6527 7317 8197 - USR VECTOR +88CD +C10E +C10E +F515 +D515 +CD15 +E115 +D109 C621 +A809 4B +C409 +E109 +B87E +CBFD CD1F - RAM TARGET _______________________________________________________________________________________________ $2017 $2025 $2030 $207A $21E3 $21EE $2205 $25D8 $2797 $2798 $27A3 $27A4 $27A8 $291D $2A2E $2A31 - ROM ADDRESS 8215 8229 8240 8314 8675 8686 8709 9688 10135 10136 10147 10148 10152 10525 10798 10801 - USR VECTOR CD1F D021 FD1F CD1F D821 8AC3 F51F D10B 2D C42A 3C C9C7 CBC9 +80F6 2A +C12A - RAM TARGET _______________________________________________________________________________________________ $2A6C $2A8A $2B49 $2B57 $2C32 $2C3E $2F5D $2FF2 $3183 $31B8 $32DF $372E $372F - ROM ADDRESS 10860 10890 11081 11095 11314 11326 12125 12274 12675 12728 13023 14126 14127 - USR VECTOR +F52A +F52A +80F6 E52B +DA2A +EB2A +A779 D0C1 D718 +CDEB AF30 4C +CDCC - RAM TARGET
Переход на зону экрана:Код:0011 F2 15 FF|JP P,$FF12 ; USR 17 00B2 D2 41 D4|JP NC,$D441 ; USR 178 (168+:$53 $43 $52 $45 $4E $A4 $41 $54 $54) 026D CD C8 CC|CALL $CCC8 ; USR 621 (620:$3F) 027C C3 3E C5|JP $C53E ; USR 636 (635:$3C, 633:$22) 0287 CA D3 D4|JP Z,$D4D3 ; USR 647 0289 D4 D1 D2|CALL NC,$D2D5 ; USR 649 028B D2 A9 CF|JP NC,$CFA5 ; USR 651 02AA F4 2D CB|CALL P,$CB2D ; USR 682 0598 D4 30 F4|CALL NC,$F430 ; USR 1432 0774 F2 3E FE|JP P,$FE3E ; USR 1908 0982 D4 15 DD|CALL NC,$DD15 ; USR 2434 (2432:$EE) 0A88 F4 09 CD|CALL P,$CD09 ; USR 2696 0B8F CD 0E D1|CALL $D10E ; USR 2859 0D9D F4 09 A7|CALL P,$A709 ; USR 3485 0E37 CD CD 88|CALL $88CD ; USR 3639 0EB5 F4 0E C1|CALL P,$C10E ; USR 3765 0ED5 F4 0E C1|CALL P,$C10E ; USR 3797 0F39 D4 15 F5|CALL NC,$F515 ; USR 3897 0F6D D4 15 D5|CALL NC,$D515 ; USR 3949 101F D4 15 CD|CALL NC,$CD15 ; USR 4127 1022 D4 15 E1|CALL NC,$E115 ; USR 4130 1162 F4 09 D1|CALL P,$D109 ; USR 4450 127B CA 21 C6|JP Z,$C621 ; USR 4731 15AF F4 09 A8|CALL P,$A809 ; USR 5551 15B4 F4 09 C4|CALL P,$C409 ; USR 5556 (5555:$4B) 18D5 F4 09 E1|CALL P,$E109 ; USR 6357 197F F4 7E B8|CALL P,$B87E ; USR 6527 1C95 F4 FD CD|CALL P,$CBFD ; USR 7317 2005 C3 1F CD|JP $CD1F ; USR 8197 2017 C3 1F CD|JP $CD1F ; USR 8215 2025 F2 21 D0|JP P,$D021 ; USR 8229 2030 C3 1F FD|JP $FD1F ; USR 8240 207A C3 1F CD|JP $CD1F ; USR 8314 21E3 F2 21 D8|JP P,$D821 ; USR 8675 21EE F2 C3 8A|JP P,$8AC3 ; USR 8686 2205 C3 1F F5|JP $F51F ; USR 8709 25D8 F2 0B D1|JP P,$D10B ; USR 9688 2798 C3 2A C4|JP $C42A ; USR 10136 (10135:$2D) 27A4 CD C7 C9|CALL $C9C7 ; USR 10148 (10147:$3C) 27A8 C3 C9 CB|JP $CBC9 ; USR 10152 291D F4 F6 80|CALL P,$80F6 ; USR 10525 2A31 F4 2A C1|CALL P,$C12A ; USR 10801 (10798:$2A) 2A6C CD 2A F5|CALL $F52A ; USR 10860 2A8A CD 2A F5|CALL $F52A ; USR 10890 2B49 F4 F6 80|CALL P,$80F6 ; USR 11081 2B57 EA 2B E5|JP PE,$E52B ; USR 11095 2C32 CC 2A DA|CALL Z,$DA2A ; USR 11314 2C3E F4 2A EB|CALL P,$EB2A ; USR 11326 2F5D F4 79 A7|CALL P,$A779 ; USR 12125 2FF2 F2 C1 D0|JP P,$D0C1 ; USR 12274 3183 EA 18 D7|JP PE,$D718 ; USR 12675 31B8 F4 EB CD|CALL P,$CDEB ; USR 12728 32DF CA 30 AF|JP Z,$AF30 ; USR 13023 372F CC CC CD|CALL Z,$CDCC ; USR 14127 (14126:$4C)
Код:00A7 D4 53 43|CALL NC,$4353 ; USR 167 (163+:$50 $4F $49 $4E) 00B4 D4 54 41|CALL NC,$4154 ; USR 180 (179:$41) 00C2 CC 4C 45|CALL Z,$454C ; USR 194 (188+:$43 $4F $44 C5 56 41) 00DF D4 53 51|CALL NC,$5153 ; USR 223 (221+:$49 $4E) 00E2 D2 53 47|JP NC,$4753 ; USR 226 (224+:$53 $51) 00F1 D2 53 54|JP NC,$5453 ; USR 241 (239+:$55 $53) 00FC D4 42 49|CALL NC,$4942 ; USR 252 (242+:$53 $54 $52 $A4 $43 $48 $52 $A4 $4E $4F) 0101 D2 41 4E|JP NC,$4E41 ; USR 257 (256:$4F) 0121 D4 46 4F|CALL NC,$4F46 ; USR 289 (287+:$43 $41) 0127 D4 4D 4F|CALL NC,$4F4D ; USR 295 (290+:$46 $4F $52 $4D $41) 015A D2 46 4C|JP NC,$4C46 ; USR 346 (339+:$49 $4E $CB $50 $41 $50 $45) 0165 D4 49 4E|CALL NC,$4E49 ; USR 357 (352+:$42 $52 $49 $47 $48) 0170 D2 4F 55|JP NC,$554F ; USR 368 (365+:$4F $56 $45) 0173 D4 4C 50|CALL NC,$504C ; USR 371 (369+:$4F $55) 0179 D4 4C 4C|CALL NC,$4C4C ; USR 377 (372+:$4C $50 $52 $49 $4E) 017E D4 53 54|CALL NC,$5453 ; USR 382 (378+:$4C $4C $49 $53) 019A D2 43 4F|JP NC,$4F43 ; USR 410 (405+:$42 $4F $52 $44 $45) 01A5 CD 52 45|CALL $4552 ; USR 421 (419+:$44 $49) 01A8 CD 46 4F|CALL $4F46 ; USR 424 (422+:$52 $45) 01AB D2 47 4F|JP NC,$4F47 ; USR 427 (425+:$46 $4F) 01BB D4 4C 4F|CALL NC,$4F4C ; USR 443 (433+:$47 $4F $20 $53 $55 $C2 $49 $4E $50 $55) 01C3 D4 4C 45|CALL NC,$454C ; USR 451 (444+:$4C $4F $41 $C4 $4C $49 $53) 01C6 D4 50 41|CALL NC,$4150 ; USR 454 (452+:$4C $45) 01CF D4 50 4F|CALL NC,$4F50 ; USR 463 (460+:$4E $45 $58) 01D8 D4 50 4C|CALL NC,$4C50 ; USR 472 (468+:$50 $52 $49 $4E) 01DC D4 52 55|CALL NC,$5552 ; USR 476 (473+:$50 $4C $4F) 01FA D2 52 45|JP NC,$4552 ; USR 506 (502+:$43 $4C $45 $41) 026F CC CB 5E|CALL Z,$5ECB ; USR 623[свернуть]
Адресов несколько больше, но из-за комбинации флажков и условным переходам они не срабатывают как надо…
P.S.: Может я «открыл Америку»…
Но, думаю, вопрос довольно интересен.