Может ли кто-нибудь помочь мне понять язык ассемблера? - PullRequest
0 голосов
/ 09 мая 2020

Извините, это не то место, но я отчаянно пытаюсь понять, что происходит в этом скрипте сборки (я предполагаю, что это то, что есть, основываясь на часах поиска в Google, которые я сделал .) Это ром для версии Pokemon Yellow, и я понимаю некоторые, но не все. Я полагаю, что если мне удастся получить некоторую помощь в понимании того, что делает этот один абзац, я смогу понять остальное. Код выглядит так:

PalletTownScript:
    CheckEvent EVENT_GOT_POKEBALLS_FROM_OAK
    jr z, .next
    SetEvent EVENT_PALLET_AFTER_GETTING_POKEBALLS
.next
    call EnableAutoTextBoxDrawing
    ld hl, PalletTownScriptPointers
    ld a, [wPalletTownCurScript]
    jp JumpTable

Насколько я понимаю, первая строка просто помещает остальную часть в метку с именем «PalletTownScript», просто имя, на которое будет ссылаться позже. Вторая строка проверяет, что произошло определенное событие, подробно описанное в другом файле. Пока все в порядке. В третьей строке для меня все усложняется. Я определил, что «jr» переходит к другому разделу скрипта, а затем возвращается сюда? Думаю? Но из того, что я видел, каждый пример имеет только один аргумент, а в этой строке - два. Это прыгает на z? Что такое z? Я просмотрел оставшуюся часть этого файла, и там нет раздела с именем z. Z еще одна функция? Другой аргумент - .next, который, насколько я могу судить, является подразделом раздела PalletTownScript. Так что имеет смысл, что он прыгает там (но зачем вообще прыгать? Если он прямо там, разве он все равно не сделает это?) Но я до сих пор не знаю, что там делает z. В .next он вызывает некоторые вещи и загружает другие, все в порядке, но в конце он переходит к JumpTable, который находится в другом файле (я предполагаю, что это не имеет значения после того, как все скомпилировано, поэтому я меня это не беспокоит), но выполняется ли переход к .next, а затем снова к JumpTable? Когда он go вернется к этому SetEvent? Где это go после этого?

Я никогда раньше не имел дела с Assembly, и все это меня очень сбивает с толку, поэтому, если бы кто-то мог мне помочь с этим, я был бы очень признателен. Спасибо!

Ответы [ 2 ]

3 голосов
/ 09 мая 2020

jr z, .next - условный относительный переход. Переход будет выполнен, только если установлен флаг Zero (в регистре F).

Если событие EVENT_GOT_POKEBALLS_FROM_OAK уже произошло, устанавливается событие EVENT_PALLET_AFTER_GETTING_POKEBALLS.

Если это не так, SetEvent EVENT_PALLET_AFTER_GETTING_POKEBALLS пропускается.

Макросы CheckEvent и SetEvent определены здесь: https://github.com/pret/pokered/blob/master/macros/event_macros.asm

0 голосов
/ 09 мая 2020

Программа на ассемблере должна читаться построчно. Каждая строка может быть

  1. комментарием (игнорируется ЦП),
  2. меткой (символ c имя этого места в программе),
  3. машиной инструкция (приказ ЦП выполнить какое-либо действие),
  4. макрос (символ c имя группы машинных инструкций, которые определены где-то еще в исходном файле или в каком-либо другом исходном файле, включенном в основной источник )

Мысленно визуализируйте каждое утверждение как черный ящик , который что-то делает. Чтобы понять каждый оператор, он должен задокументировать свой ввод, то, что он делает, каков вывод, есть ли какие-либо сопутствующие убытки (затертые регистры или флаги, несбалансированный стек, исключения). CPU выглядит как Zilog Z80, мнемони c ярлыки его машинных инструкций перечислены в http://nemesis.lonestar.org/computers/tandy/software/apps/m4/qd/opcodes.html вместе с кратким объяснением. В вашем фрагменте мы можем распознать машинные инструкции jr, call, ld, jp. Z80 имеет 8-битные регистры a, b, c, d, e, h, l, некоторые из них могут быть объединены в 16-битную пару: bc, de, hl. Он также имеет 1-битные «регистры» z, c, p, называемые флаги , которые могут быть установлены или сброшены некоторыми инструкциями и, таким образом, напоминают результат предыдущего оператора. Процессор может разветвлять свое дальнейшее выполнение согласно флагам, используя условные переходы , например jr z, .next. Если предыдущий оператор установил флаг z на true , jr переходит к .next, иначе jr игнорируется. В ярлыках нет magi c, это просто способ ассемблера указать пальцем на конкретное место в потоке программы.

Если вы хотите знать, было ли z установлено или сброшено предыдущим оператором CheckEvent EVENT_GOT_POKEBALLS_FROM_OAK, вам нужно будет набрать CheckEvent с помощью grep во включенных исходных файлах и надеяться, что определение макроса было предоставлено вместе с его документацией. Ярлыки, символы и имена макросов в Pokemon ROM разговорчивы (что, к сожалению, не всегда так в программах asm), поэтому легко догадаться, что макрос сбрасывает флаг z, когда EVENT_GOT_POKEBALLS_FROM_OAK (что бы это ни значило) произошел, иначе следующий условный переход приказывает ЦП пропустить макроинструкцию SetEvent EVENT_PALLET_AFTER_GETTING_POKEBALLS и продолжайте до метки .next.

.

...