我使用ltrace和objdump來分析下面的簡單代碼。但我發現 ltrace 和 objdump 之間顯示的指令地址存在差異。
#include <iostream>
int main() {
std::cout << "Hello";
return 0;
}
如以下資訊,您可以看到 [call std::basic_ostream] 在 ltrace 中的地址為 [0x400789]。(0x400789 是指令“call”的地址,而不是 std::basic_ostream)
binary@binary-VirtualBox:~/code/chapter5/test$ ltrace -i -C ./a.out
[0x4006a9] __libc_start_main(0x400776, 1, 0x7fff06c6ad28, 0x4007f0 <unfinished ...>
[0x4007b7] std::ios_base::Init::Init()(0x601171, 0xffff, 0x7fff06c6ad38, 160) = 0
[0x4007cb] __cxa_atexit(0x400650, 0x601171, 0x601048, 0x7fff06c6ab00) = 0
[0x400789] std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)(0x601060, 0x400874, 0x7fff06c6ad38, 192) = 0x601060
[0x7f220180aff8] std::ios_base::Init::~Init()(0x601171, 0, 0x400650, 0x7f2201b96d10Hello) = 0x7f2201f19880
[0xffffffffffffffff] exited (status 0)
但是,objdump 中顯示的 [call std::basic_ostream] 地址為 [0x400784],而另一條指令 [mov eax,0x0] 在 [0x400789] 上。其他“呼叫”指令也是如此。
0000000000400776 <main>:
400776: 55 push rbp
400777: 48 89 e5 mov rbp,rsp
40077a: be 74 08 40 00 mov esi,0x400874
40077f: bf 60 10 60 00 mov edi,0x601060
400784: e8 d7 fe ff ff call 400660 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
400789: b8 00 00 00 00 mov eax,0x0
40078e: 5d pop rbp
40078f: c3 ret
我真的很想知道是什么導致了差距。萬分感謝。
uj5u.com熱心網友回復:
這些是回傳地址(call父級中的指令,call壓入堆疊的地址)。
ltrace不知道指令呼叫函式的時間有多長,例如call reg,函式指標只有 2 個位元組,而 5 位元組,call rel32而 6位元組call [RIP rel32](如果你用 . 編譯,GCC 將使用記憶體間接呼叫-fno-plt。)
或者,如果它是尾部呼叫的,則執行將從 ajmp或某處到達它,因此即使在具有固定長度指令(如 MIPS 或 AArch64)的 ISA 上,ltrace仍然無法可靠地列印呼叫它的位置。最好不要嘗試制作太多東西并保持簡單,列印它可以在呼叫堆疊上實際看到的地址。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/454203.html
上一篇:使用未初始化的值$5并且引數在數字lt(<)中不是數字
下一篇:匯編:為什么堆疊上有空記憶體?
