Ассемблер C166 разобрать несколько строк
-
-
15.09.2022 #76578
Николай
КлючникИммоБокс 15 сен 2022, 13:10Приветствую. Сорри за детский вопрос. Пишу на ассемблере для Atmega, а в этом ассме туплю и не до конца въезжаю, пытаясь дизассемблировать код, следующие строчки:
, =============== S U B R O U T I N E =======================================
sub_EE922: , CODE XREF: sub_D3478+220P
, sub_D3478+294P …
mov [-r0], r9 ,
mov [-r0], r8 ,
mov [-r0], r7
mov [-r0], r6
sub r0, #0Ch , ,
mov r4, #6824h
mov r10, #6
add r10, r0 ,
mov r3, #6 ,
calls 0Eh, sub_EEA3E
===============================================
==========================
=================
sub_EEA3E:
movb [r10],[r4+] , тут видимо цикл переноса 6 байт начиная с адреса #6824h, но куда? в стек?
add [r10],#1
cmpd1 r3,#1
jmpr cc_UGT, sub_EEA3E
=============================mov [-r0], r9
mov [-r0], r8
mov [-r0], r7
mov [-r0], r6Вот это, я так понимаю сохранение регистров r9…r6 в пользовательском стеке. Видимо регистр Context Pointer (CP) указывает на r0, как на базу текущего банка GPR.
А как понять следующую строку:sub r0, #0ChПо аналогии с AVR, я понимаю, что это вычитание из содержимого 16-ти битного регистра r0, значения 0x0C.
Но как понять что там было за значение до этого? Или это опять какая-то работа с пользовательским стеком, например <,CP>,-0x0C ?NStorm 15 сен 2022, 13:52The Keil C166 Compiler uses R0 to maintain a user stack for local variables and function arguments.
The startup code in START166.A166 and START167.A66 includes a section which sets up the user stack.
The user stack grows from the top down. So, as arguments are pushed on the stack, R0 decreases.
Under normal circumstances, C166 uses just one of the 16 potential stack pointers (i.e. general
purpose registers), namely R0. The stack created by R0 is placed in a special section in NDATA
called ?C_USERSTACK. The “user stack” with R0 as its user stack pointer is used by C166 for
parameter passing and local automatic variables. When a function is called, any variables or other
data that cannot be fitted into registers are “pushed” on to the user stack by the MOV [R0-],
parameter instruction. The “R0-“ causes R0 to point at the next free location on the user stack.
Once in the called function, the parameter is moved off the user stack by the inverse instruction
MOV reg, [R0+]. Note that the R0+ moves the user stack point. As with the true system
stack pointer, SP, every MOV [R0-],xxx is matched with a MOV xxx, [R0+] so that the
user stack pointer is always restored to its original value after a function call.
Due to C166 placing up to 8 parameters and 15 locals (automatics) in registers, it is fairly rare for
the user stack to be used at all. If the optimizer is disabled, you will instantly see a large number
of MOV [-R0], R11 type instructions as C166 starts to move things onto the user stack.
docs.eao.hawaii.edu/JCMT/i/012_H … NT_124.PDFПо аналогии с AVR, я понимаю, что это вычитание из содержимого 16-ти битного регистра r0, значения 0x0C.Не знаком с архитектурой, но исходя из описания выше, r0 – keil использует как указатель на пользовательский стек. Соотв. это смещает адрес стека. Вообще это всё – запихивание в стек параметров и смещение адреса стека – похоже изначально было вызовом функции на Си, параметры в функцию так передаются. По ссылке выше пример есть похожий.
ИммоБокс 15 сен 2022, 15:09NStorm писал(а):Не знаком с архитектурой, но исходя из описания выше, r0 – keil использует как указатель на пользовательский стек. Соотв. это смещает адрес стека. Вообще это всё – запихивание в стек параметров и смещение адреса стека – похоже изначально было вызовом функции на Си, параметры в функцию так передаются. По ссылке выше пример есть похожий.Спасибо! Я так и подумал, что в стек запихивают 🙂 И за ссылку тоже спасибо!
Ещё последний вопрос, если можно, что-то я не понимаю логику вот таких строк :
movb r14, [r12+4]
mov r14, r4
загрузка в r14 байта(byte) из ячейки памяти из адреса в r12 со смещением 4
,но следующей строкой загрузка слова(word) в этот же r14 !
Оно же затрёт первое загруженное значение!
Хотя, если эту строку: movb r14, [r12+4] игнорировать, то далее вроде похоже нормально разбирается программа. Может это просто грязь в коде и это нужно просто игнорить? Или я совсем ничего не понимаю :))u37 15 сен 2022, 15:49Попробуйте другим disasm.
Я не знаю asm этого процессора, но последовательностьmovb r10,r4+ , тут видимо цикл переноса 6 байт начиная с адреса #6824h, но куда? в стек?
add r10,#1
cmpd1 r3,#1
jmpr cc_UGT, sub_EEA3Eэто НЕ переписывание 6 байт. Переписывание оно было-бы, если бы было так:
movb r10,r4+ , тут видимо цикл переноса 6 байт начиная с адреса #6824h, но куда? в стек?
add r10,#1 ,!
cmpd1 r3,#1
jmpr cc_UGT, sub_EEA3EИммоБокс 15 сен 2022, 18:30u37 писал(а):Попробуйте другим disasm.Сейчас в IDA делаю, было конечно предположение, что кривовато разобрано, но я списываю скорее на свою кривость… А какой дизасм посоветуете для C167 ?
NStorm 16 сен 2022, 17:09ИммоБокс писал(а):загрузка в r14 байта(byte) из ячейки памяти из адреса в r12 со смещением 4
,но следующей строкой загрузка слова(word) в этот же r14 !
Оно же затрёт первое загруженное значение!Может по какой-то причине нужно было просто обратиться к адресу [r12+4]? Опять же не знаком с архитектурой, но может там адрес периферии какой-нибудь и при чтении аппаратно что-то происходит. Просто гадаю.
u37 16 сен 2022, 18:48Вообще, всего 3 спорных инструкции
add [r10],#1
и ранее
movb r14, [r12+4]
mov r14, r4
В инструкции на C166 приведено оприсание opcode, за пару минут эти байты бинарника разбираются и сразу становится понятно – ошибка это или действительно такой код.ИммоБокс 20 сен 2022, 10:42u37 писал(а):Вообще, всего 3 спорных инструкции
add [r10],#1
и ранее
movb r14, [r12+4]
mov r14, r4
В инструкции на C166 приведено оприсание opcode, за пару минут эти байты бинарника разбираются и сразу становится понятно – ошибка это или действительно такой код.Дело было не в бобине(с) это мой косяк, (2шт):
1) add [r10],#1 это я руками сюда писал, а не Ctrl+V и написал херню, в оригинале было правильно: add r10,#1
2)
movb r14, [r12+4]
mov r14, r4
В IDA шрифт зараза такой(в отличие от этого шрифта), что цифра 1 почти не отличается от l (L) !!!
В реальности там следующие строки:
movb rl4, [r12+4]
mov r14, r4
И тогда всё становится на свои места… Поменял в настройках ida шрифт на другой, чтобы глаза не сломались в попытках различить 1 и l(L)
Спасибо за помощь!ИммоБокс 20 сен 2022, 14:07Если можно, то есть ещё загвоздка (тяжеловато всё же после 8ми битного ассемблера для Atmega 🙂 ):
…………………. ,
movb RL6,#5 , инициализация значения смещения, заносим byte = 0x05 в младший регистр r6
loc_XXXX:
movbz R4,RL6 , поместить byte смещение в R4, с обнулением старшего (RH4)
add R4,R0 , сложить смещение с значением SP, которое живёт видимо в R0
movb RL5, [r4+0FFFFh] , а вот это сложно к пониманию… поместить в RL5 byte с адреса [(SP+5)+0xFFFF] ???
чет как-то дофига вроде какой-то адрес получается…
………………..
………………..u37 20 сен 2022, 14:25Внимательно посмотрите список команд/операндов в C166.
Для выборки со смещением есть только один вариант:
Rwn, [Rwm+#d16]
ПЛЮС. МИНУСА нет. Уже сами поняли? )) Ответ под спойлером.movb RL5, r4+0FFFFhЧто есть 0FFFFh???
movb RL5, r4+-1ИммоБокс 20 сен 2022, 16:04u37 писал(а):Внимательно посмотрите список команд/операндов в C166.
Для выборки со смещением есть только один вариант:
Rwn, [Rwm+#d16]
ПЛЮС. МИНУСА нет. Уже сами поняли? )) Ответ под спойлером.movb RL5, r4+0FFFFhЧто есть 0FFFFh???
movb RL5, r4+-1Теперь понял! Спасибо, что нянчитесь с моими детскими вопросами 🙂
-
- Вы должны войти в систему, чтобы ответить в этой теме.