| Разработка и ромхакинг > Ромхакинг |
| GBA прыжок и возврат |
| (1/1) |
| consolegamer:
Добрый день. Хочу модифицировать игру на гба. Но мне не понятно, как делать прыжок на адрес памяти и возврат. В денди и сега умею, там просто, а вот в гба пока что никак не получается разобраться. SDK пробовал ставить, но не могу в нём разобраться. Может кто-нибудь подскажет опкод прыжка на адрес 087FFF50 и возврата? опкод формируется непонятным образом. С помощью дизассемблера увидел код игры, и вроде бы нашёл прыжок: опкод инструкция вероятно адрес памяти, на который идёт прыжок 35 f0 ee fa bl FUN_08035864 undefined FUN_08035864() Попробовал сам написать такую же инструкцию в гба-ассемблере goldroad и скомпилировать, но скомпилированная команда не понимается эмулятором гба, что кажется означает то, что goldroad не правильно работает Прыжки вроде бы осуществляются командой bx |
| Sharpnull:
У GBA процессор ARM, поэтому смотреть инструкции к нему. Инструкция b для "прыжка" без условий, относительно PC, т. е. от места вставки инструкции. bl "прыжок" на функцию и bx возврат из неё (нужен параметр, обычно lr он же r14). Абсолютные "прыжки" сложнее. Эксперименты можно делать в no$gba, ПКМ по коду > Change Instruction. Но я не разбираюсь, курите доки. |
| bugmenot:
http://problemkaputt.de/gbatek-arm-cpu-reference.htm |
| DrMefistO:
Вот тут можно потренироваться в ассемблировании, и сразу же проверить как дизассемблируется: https://shell-storm.org/online/Online-Assembler-and-Disassembler/ |
| consolegamer:
--- Цитата: DrMefistO от 09 Октябрь 2023, 00:09:40 ---Вот тут можно потренироваться в ассемблировании, и сразу же проверить как дизассемблируется: https://shell-storm.org/online/Online-Assembler-and-Disassembler/ --- Конец цитаты --- ооочень помогает Добавлено позже: --- Цитата: Sharpnull от 08 Октябрь 2023, 12:08:15 ---У GBA процессор ARM, поэтому смотреть инструкции к нему. Инструкция b для "прыжка" без условий, относительно PC, т. е. от места вставки инструкции. bl "прыжок" на функцию и bx возврат из неё (нужен параметр, обычно lr он же r14). Абсолютные "прыжки" сложнее. Эксперименты можно делать в no$gba, ПКМ по коду > Change Instruction. Но я не разбираюсь, курите доки. --- Конец цитаты --- как я понял, адрес, на который прыгаешь, собирается в регистре r1(например) и на него делается прыжок bx r1 Если я правильно понял, процессор гба работает с 32х битными командами только в определенном диапазоне памяти(0x03000000-...) и с 16битными командами в диапазоне 0x08000000-..., что создало проблемы при прыжке. |
| DrMefistO:
--- Цитата: consolegamer от 11 Октябрь 2023, 09:57:43 ---Если я правильно понял, процессор гба работает с 32х битными командами только в определенном диапазоне памяти(0x03000000-...) и с 16битными командами в диапазоне 0x08000000-..., что создало проблемы при прыжке. --- Конец цитаты --- Никто же не мешает в регистр поместить любое число и прыгнуть на него. |
| Sharpnull:
--- Цитата: consolegamer от 11 Октябрь 2023, 09:57:43 ---процессор гба работает с 32х битными командами только в определенном диапазоне памяти(0x03000000-...) и с 16битными командами в диапазоне 0x08000000-..., что создало проблемы при прыжке. --- Конец цитаты --- Не понял что за проблемы, диапазон 08000000- просто дольше выполняется для 32-битных инструкций из-за шины в 16 бит, поэтому там лучше выполнять THUMB инструкции (16 бит) или скопировать код во внутреннюю память (Work RAM 32K 03000000-03007FFF), как написано в CPU Mode Performance: https://problemkaputt.de/gbatek-gba-memory-map.htm. |
| consolegamer:
--- Цитата: Sharpnull от 11 Октябрь 2023, 17:25:24 ---Не понял что за проблемы, диапазон 08000000- просто дольше выполняется для 32-битных инструкций из-за шины в 16 бит, поэтому там лучше выполнять THUMB инструкции (16 бит) или скопировать код во внутреннюю память (Work RAM 32K 03000000-03007FFF), как написано в CPU Mode Performance: https://problemkaputt.de/gbatek-gba-memory-map.htm. --- Конец цитаты --- ну я пробовал писать 32х битные команды в диапазоне 08000000-, а cpu-трэйсер VisualBoyAdvance-SDL-H показал мне, что 32хбитные команды выполнились как 16битные, т.е .выполнились не правильно. может нужно какую-то команду давать, чтобы переключаться, я не программист)) я просто ещё не умею делать прыжки на 16 битных командах, в этом у меня проблема. а так то да, никаких проблем у специалистов. |
| consolegamer:
Подскажите пож-та, если можете. Я делаю прыжок в месте, где выполняются 16битные команды, на ram-адрес 08800000, что соответствует концу рома, процессор сам при этом меняет режим и начинает исполнять команды в 32 битном режиме, далее делаю возврат, и он не переключается обратно на 16битный режим. 5 дней уже пытаюсь сделать. Вот лог процессора, в который я добавил комментарии: Собираю адрес в регистре r1 и делаю прыжок 080754FA 2188 mov r1, #0x88 R00=00000014 R01=0000001a R02=0000000f R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=080754fc 080754FC 0509 lsl r1, r1, #0x14 R00=00000014 R01=00000088 R02=0000000f R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=080754fe 080754FE 4708 bx r1 R00=00000014 R01=08800000 R02=0000000f R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=08075500 Восстанавливаю старые команды, которые я затёр прыжком, но уже в 32битном режиме 08800000 e0900004 adds r0, r0, r4 R00=00000014 R01=08800000 R02=0000000f R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=08800004 08800004 e3a02000 mov r2, #0x0 R00=0807c94c R01=08800000 R02=0000000f R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=08800008 08800008 e19000f2 ldrsh r0, [r0, r2] R00=0807c94c R01=08800000 R02=00000000 R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=0880000c Собираю адрес в регистре, чтобы прыгнуть на него, т.е. вернуться обратно 0880000C e3a01008 mov r1, #0x8 R00=fffffb9b R01=08800000 R02=00000000 R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=08800010 08800010 e1b01601 movs r1, r1, lsl #0x0c R00=fffffb9b R01=00000008 R02=00000000 R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=08800014 08800014 e2811075 add r1, r1, #0x75 R00=fffffb9b R01=00008000 R02=00000000 R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=08800018 08800018 e1b01201 movs r1, r1, lsl #0x04 R00=fffffb9b R01=00008075 R02=00000000 R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=0880001c 0880001C e2811005 add r1, r1, #0x5 R00=fffffb9b R01=00080750 R02=00000000 R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=08800020 08800020 e1b01401 movs r1, r1, lsl #0x08 R00=fffffb9b R01=00080755 R02=00000000 R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=08800024 Прыгаю на адрес 08800024 e12fff11 bx r1 R00=fffffb9b R01=08075500 R02=00000000 R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=08800028 И тут процессор не переключается обратно на 16битный режим, а начинает выполнять 16битные команды в 32битном режиме, и игра поэтому виснет 08075500 41081109 tstmi r8, r9, lsl #0x02 R00=fffffb9b R01=08075500 R02=00000000 R03=0807c8b4 R04=0807c938 R05=00000015 R06=fffffdac R07=00000000 R08=03000e30 R09=030005cc R10=00000100 R11=000001ff R12=00000000 R13=03007e9c R14=08074885 R15=08075504 В документации написано, что режимы меняются командой bx. Прилагаю оригинальный ром, и ром с моими изменениями который виснет, с которого писал логи https://disk.yandex.ru/d/jb2-imm6xOzobw |
| Sharpnull:
--- Цитата: consolegamer от 14 Октябрь 2023, 11:05:09 ---он не переключается обратно на 16битный режим --- Конец цитаты --- В 0-м бите регистра в bx должен быть 1 для переключения в Thumb, т. е. в вашем коде нужно добавить add r1,r1,1h перед bx r1. Собрать адрес 08075501 можно короче (код 32 бита): --- Код: ---mov r1,8000000h add r1,r1,75000h add r1,r1,500h add r1,r1,1h bx r1 --- Конец кода --- Ещё короче, как генерируется инструкция ldr r0,=0x08075501, в данном случае: --- Код: ---ldr r1, [pc, #0] ; Адрес лежит через 4 байта + 0 байт (#0) bx r1 01 55 07 08 ; Байты сразу после bx r1 --- Конец кода --- Байты инструкций тогда E59F1000 E12FFF11 08075501. UPD: Вместо ADD можно использовать ORR, не знаю будет ли разница, в описании к ассемблеру FASMARM увидел макрос как раз для сборки адреса https://gbadev.org/tools.php?showinfo=1399: --- Код: ---macro imm32 reg,immediate { mov reg,immediate and $FF orr reg,immediate and $FF00 orr reg,immediate and $FF0000 orr reg,immediate and $FF000000 } Use imm32 Rd,$12345678 in your code etc... --- Конец кода --- Только нужно помнить, что макрос всегда занимает 4 инструкции, а собрать можно короче, т. к. одна инструкция включает 8 бит значения и 4 бита сдвига, поэтому для уменьшения кода ассемблер должен сам генерировать код. |
| consolegamer:
С add r1,r1,1h завелась игра . Вы - мои герои |
| DrMefistO:
А Армов есть возможность добавлять сразу со сдвигом: ADD r0, r1, r2, LSL #4 Типа того, так будет короче. |
| Sharpnull:
--- Цитата: DrMefistO от 14 Октябрь 2023, 20:22:26 ---Типа того, так будет короче. --- Конец цитаты --- Короче, чем что? Для r1=08075501 это не будет короче, чем (или orr): --- Код: ---mov r1,8000000h add r1,r1,75000h add r1,r1,500h add r1,r1,1h --- Конец кода --- Если только в других регистрах что-то есть или хитрости с другими инструкциями. Тем более не короче ldr. |
| Навигация |
| Главная страница сообщений |