#c #assembly #iar
Вопрос:
Я новичок в IAR и встроенном программировании. Я отлаживал следующий код на языке Си и обнаружил, что R0
получает возможность удерживать адрес counter1
through ??main_0
, в то время R1
как получает возможность удерживать адрес counter2
through [PC,#0x20]
. Это вполне понятно, но я не могу понять, почему он был назначен R0
для использования LDR Rd, -label
во время R1
использования LDR Rd, [PC Offset]
и в чем разница между этими двумя подходами?
Я знал о литеральных пулах только после поиска, но это не ответило на мой вопрос. Кроме того, где вы ??main_0
определились в первую очередь?
int counter1=1;
int counter2=1;
int main()
{
int *ptr;
int *ptr2;
ptr=amp;counter1;
ptr2=amp;counter2;
(*ptr);
(*ptr2);
counter2;
return 0;
}
Комментарии:
1. Пожалуйста, уточните вашу конкретную проблему или предоставьте дополнительные сведения, чтобы выделить именно то, что вам нужно. Как написано в настоящее время, трудно точно сказать, о чем вы спрашиваете.
Ответ №1:
??main_0
не «определен» как таковой, это просто автоматически сгенерированная метка для используемого здесь адреса, так что при чтении дизассемблирования вам не нужно помнить, что адрес 0x8c
— это указатель счетчика. На самом деле было бы разумно иметь другой указатель счетчика as ??main_1
, и я не уверен, почему вместо этого он показывает голый [PC, #0x20]
. Как вы можете видеть на странице 144/145 справочника по сборке IAR, эти две формы являются просто разными интерпретациями одного и того же машинного кода. Если дизассемблер решает присвоить метку адресу, он может отображать форму метки, в противном случае форму смещения.
Машинный код первой инструкции — это 48 07
, что означает LDR.N R0, [PC, #0x1C]
. Интерпретация as ??main_0
(и назначение метки ??main_0
для адреса 0x8c
в первую очередь) — это просто то, что решил сделать дизассемблер. Вы не можете знать, как выглядел исходный исходный код сборки (если он вообще существует и компилятор не компилировался непосредственно в машинный код) и использовал ли он там метку или нет.