Я хочу написать программу на C, которая будет печатать содержимое счетчика программ PC
. Можно ли это сделать из пользовательского пространства или сборки или использовать некоторые определенные подпрограммы ядра?Как напечатать точное значение счетчика программ в C
ответ
Вы должны быть в состоянии определить компьютер с помощью __current_pc()
intrinsic в инструментарии, ARM компилятор (ARM компилятор поддерживает многие из тех же расширения как GCC). * Это особенно для ARM:
int main() {
printf("%#x\n", __current_pc());
printf("%#x\n", __current_pc());
printf("%#x\n", __current_pc());
return 0;
}
* Благодаря FrankH. за указание на наличие
__current_pc()
В общем, компьютер будет сохранен как обратный адрес в вызове функции. В системах без ARM linux с GCC вы можете позвонить __builtin_return_address(0)
, чтобы получить обратный адрес текущего контекста вызова функции. Таким образом, получение счетчика программы приводит к штрафу за добавление вызова функции, но оно позволяет избежать встроенной сборки, поэтому этот метод переносится на любую систему, поддерживаемую GCC.
void * get_pc() { return __builtin_return_address(0); }
int main() {
printf("%p\n", get_pc());
printf("%p\n", get_pc());
printf("%p\n", get_pc());
return 0;
}
Когда я бегу выше программу на моей системе x86
, она выводит:
0x8048432
0x8048447
0x804845c
Когда разобранный в gdb
:
Dump of assembler code for function main:
0x08048424 <+0>: push %ebp
0x08048425 <+1>: mov %esp,%ebp
0x08048427 <+3>: and $0xfffffff0,%esp
0x0804842a <+6>: sub $0x10,%esp
0x0804842d <+9>: call 0x804841c <get_pc>
0x08048432 <+14>: mov %eax,0x4(%esp)
0x08048436 <+18>: movl $0x8048510,(%esp)
0x0804843d <+25>: call 0x80482f0 <[email protected]>
0x08048442 <+30>: call 0x804841c <get_pc>
0x08048447 <+35>: mov %eax,0x4(%esp)
0x0804844b <+39>: movl $0x8048510,(%esp)
0x08048452 <+46>: call 0x80482f0 <[email protected]>
0x08048457 <+51>: call 0x804841c <get_pc>
0x0804845c <+56>: mov %eax,0x4(%esp)
0x08048460 <+60>: movl $0x8048510,(%esp)
0x08048467 <+67>: call 0x80482f0 <[email protected]>
0x0804846c <+72>: mov $0x0,%eax
0x08048471 <+77>: leave
0x08048472 <+78>: ret
End of assembler dump.
Обратный адрес и ПК ('EIP' /' RIP') _не_ то же самое. –
извинения, в ARM Я должен сказать, что обратный адрес ('LR') и' PC' - это то же самое. –
И еще ... причина, по которой вы работаете, - это то, что вы используете функцию call_ (что делает 'LR' в вашей функции' PC' сайта вызова). Это необязательно неэффективно. –
Ну, я думаю, вы можете получить информацию, вставив сборочные блоки в свой код C. Это полностью зависит от вашего компилятора и набора регистров вашей платформы. Я сделал это так:
int get_counter1()
{
__asm__ ("lea (%rip), %eax ") ;
}
int get_counter2()
{
int x = 0;
__asm__ ("lea (%rip), %eax") ;
}
int main()
{
printf("%x\n",get_counter1());
printf("%x\n",get_counter2());
return 0;
}
4004ce
4004e1
На ARM, вы можете использовать:
static __inline__ void * get_pc(void) {
void *pc;
asm("mov %0, pc" : "=r"(pc));
return pc;
}
Или это один должен работать, а также:
static __inline__ void * get_pc(void) {
register void * pc __asm__("pc");
__asm__("" : "=r"(pc));
return pc;
}
Принудительное встраивание важно здесь, потому что гарантирует вам получить PC
согласно месту вызова.
Редактировать: только что вспомнил, __current_pc()
ARM intrinsic. GCC также должен иметь это.
- 1. Нулевое значение счетчика программ
- 2. Неверное значение счетчика программ: 0
- 3. Недопустимое значение счетчика программ в MIPS
- 4. Как напечатать на экране значение счетчика masm32
- 5. Какое точное содержимое стека программ в C?
- 6. Переполнение счетчика программ?
- 7. Как получить значение счетчика программ из Stack on PIC18F
- 8. Eclipse-Plugin: Позиция счетчика программ
- 9. Как напечатать точное количество символов из: text?
- 10. Инструкция Указатель против счетчика программ?
- 11. C# Linq получить точное значение
- 12. Перемещение счетчика программ в Delphi Отладка
- 13. Как напечатать очень большое значение в c
- 14. как напечатать значение аргументов в C
- 15. Как напечатать значение в консольном приложении C#
- 16. Как напечатать/проверить значение вектора в C++
- 17. C# Поплавок не вставляет, как точное значение
- 18. Указатель стека/Ошибка счетчика программ MIPs
- 19. Отдел в C#, чтобы получить точное значение
- 20. Как напечатать логическое значение?
- 21. Каково точное значение «int const *» в C?
- 22. Каково точное значение выражения extern в C++?
- 23. Значения регистра счетчика программ для Java-программы
- 24. Инкремент счетчика программ по адресу филиала
- 25. Сбой из-за недействительного счетчика программ
- 26. Как получить точное точное время C++
- 27. Как сбросить значение счетчика?
- 28. Как совместить точное значение в elasticsearch?
- 29. Изменить счетчик программ в C
- 30. Какова ценность счетчика программ при использовании их в инструкции? (Монтаж)
Код отладчика контролирует/получает доступ к ПК, поэтому я должен использовать способ построения встроенной сборки. –
@GrijeshChauhan: Как вы думаете, может быть расширение GCC для счетчика программ? –
Да, я не очень уверен, но я чувствую, что над этим примечанием должен быть какой-то способ: если в коде у вас есть 'lable:', то вы можете распечатать его адрес, используя '& lable' (это заставляет меня сказать« да »). Очень задний код (законный) использует этот вид инструкций, но часто использует код вредоносного кода, поэтому его хорошая функция. –