Chcę napisać program w języku C, który wydrukowałby zawartość licznika programu PC
. Czy można to zrobić z przestrzeni użytkownika, zespołu lub z niektórych konkretnych procedur jądra?Jak wydrukować dokładną wartość licznika programu w C
Odpowiedz
Powinieneś być w stanie określić komputer za pomocą __current_pc()
intrinsic w toolchain ARM kompilatora (kompilator ARM obsługuje wiele tych samych rozszerzenia jako GCC). * Jest to szczególnie ARM:
int main() {
printf("%#x\n", __current_pc());
printf("%#x\n", __current_pc());
printf("%#x\n", __current_pc());
return 0;
}
* Dzięki FrankH. za wskazanie obecności
__current_pc()
W ogóle, komputer zostaje zapisany jako adres zwrotny w wywołaniu funkcji. W systemach innych niż ARM linux z GCC można wywołać __builtin_return_address(0)
, aby uzyskać adres powrotu bieżącego kontekstu wywołania funkcji. Uzyskanie licznika programu w ten sposób pociąga za sobą karę dodania wywołania funkcji, ale unika on wbudowanego zestawu, więc technika ta jest przenośna do dowolnego systemu obsługiwanego przez 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;
}
Kiedy uruchomić powyższy program w moim systemie x86
, produkuje wyjście:
0x8048432
0x8048447
0x804845c
Podczas demontażu w 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.
adres zwrotny i komputer ('EIP' /' RIP') to _nie to samo. –
Przepraszam, w ARM, powiem, adres zwrotny ('LR') i' PC' są _nie_ to samo. –
I więcej ... powód, dla którego działa twój, polega na tym, że _force wywołuje funkcję call_ (która czyni 'LR' w twoim funku' PC' strony wywołania). Jest to niepotrzebnie nieefektywne. –
Cóż, myślę, że można uzyskać informacje, wstawiając bloki montażowe do kodu C. To będzie całkowicie zależało od twojego kompilatora i zestawu rejestrów twojej platformy. zrobiłem to tak:
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
na ramieniu, można użyć:
static __inline__ void * get_pc(void) {
void *pc;
asm("mov %0, pc" : "=r"(pc));
return pc;
}
Albo ten powinien działać jak dobrze:
static __inline__ void * get_pc(void) {
register void * pc __asm__("pc");
__asm__("" : "=r"(pc));
return pc;
}
Wymuszony inline jest tutaj ważne, bo gwarantuje Ci odzyskać PC
jak na miejscu wywołania.
Edytuj: Właśnie zapamiętany, __current_pc()
ARM intrinsic. GCC również powinno to mieć.
- 1. Jak wydrukować malajalam jako wyjście programu c/C++?
- 2. Jak wydrukować datę w C?
- 3. jak wydrukować bool w celu c
- 4. jak wydrukować całą wartość wyliczenia w java?
- 5. Jak wydrukować wartość obiektu Tensor w TensorFlow?
- 6. Jak wydrukować wartość boolowską w Go?
- 7. jak wydrukować wartość std :: map w gdb
- 8. Jak wydrukować wartość konsoli w moim Eclipse?
- 9. Jak wydrukować wartość zmiennej przez NSLog?
- 10. Jak wydrukować Unicode za pomocą programu NCurses?
- 11. jQuery - Zwiększ wartość licznika po kliknięciu przycisku
- 12. Jak wykryć dokładną długość w regex
- 13. Jak ustawić dokładną wysokość listbox w Windows Forms (C#)?
- 14. Jak wydrukować wartość tej wartości boolowskiej? (Java)
- 15. Jak wydrukować bieżący czas w C++ 11?
- 16. Jak wydrukować plik pcl w języku C#?
- 17. Jak wydrukować znak procentu (%) w c
- 18. Jak wydrukować zawartość pamięci zmiennej w C?
- 19. Jak wydrukować elementy wektora C++ w GDB?
- 20. jak wydrukować ciąg na konsolę w C++
- 21. wydrukować wartość zmiennej w Python/Django?
- 22. gdb - jak wydrukować wynik oceny dla C++
- 23. Jak zaimplementować Asynchronię zadań dla licznika w języku C#?
- 24. Jak utworzyć dokładne zdarzenie licznika czasu w Objective-C/iOS?
- 25. Android: Jak uzyskać dokładną wysokość?
- 26. Jak wydrukować określoną wartość JSON w języku Python?
- 27. Zwiększanie licznika w bazie danych
- 28. Jak uzyskać dokładną ścieżkę do "Moich dokumentów"?
- 29. Jak wydrukować wartości z rozszerzeń C?
- 30. Aktualizacja licznika w XQuery
Kontrola kodu debuggera/dostęp do komputera, więc powinien być sposób, w jaki myślę przy użyciu wbudowanego zestawu. –
@GrijeshChauhan: Czy sądzisz, że może istnieć rozszerzenie GCC dla licznika programu? –
Tak, nie jestem do końca pewny, ale uważam, że powinno być jakiś sposób obejścia tej notatki: jeśli w kodzie masz 'label: ', możesz wydrukować jego adres używając' & lable' (to sprawia, że mówię tak). Bardzo kod tylny (zgodny z prawem) używa tego rodzaju instrukcji, ale często używa go w kodzie złośliwego oprogramowania, więc jest to dobra funkcja. –