有没有一种简单的方法可以在执行C程序时快速计算执行的指令数量(x86指令 - 每个指令的数量和数量)?
我在gcc version 4.7.1 (GCC)
机器上使用x86_64 GNU/Linux
。
可能是this question的副本
我说可能是因为你要求汇编程序指令,但是这个问题处理代码的C级分析。
但是,我的问题是:为什么要描述执行的实际机器指令?作为第一个问题,各种编译器和它们的优化设置之间会有所不同。作为一个更实际的问题,你真的可以用这些信息做些什么?如果您正在搜索/优化瓶颈,那么代码分析器就是您正在寻找的。
不过,我可能会错过一些重要的事情。
您可以使用硬件性能计数器(HPC)轻松计算执行指令的数量。要访问HPC,您需要一个接口。我建议你使用PAPI Performance API。
虽然不是“快速”取决于程序,这可能已经回答in this question。在这里,Mark Plotnick建议使用gdb
观察您的程序计数器寄存器更改:
# instructioncount.gdb
set pagination off
set $count=0
while ($pc != 0xyourstoppingaddress)
stepi
set $count++
end
print $count
quit
然后,在您的程序上启动gdb
:
gdb --batch --command instructioncount.gdb --args ./yourexecutable with its arguments
要获取结束地址0xyourstoppingaddress
,您可以使用以下脚本:
# stopaddress.gdb
break main
run
info frame
quit
它在函数main
上放置一个断点,并给出:
$ gdb --batch --command stopaddress.gdb --args ./yourexecutable with its arguments
...
Stack level 0, frame at 0x7fffffffdf70:
rip = 0x40089d in main (main_aes.c:33); saved rip 0x7ffff7a66d20
source language c.
Arglist at 0x7fffffffdf60, args: argc=3, argv=0x7fffffffe048
...
这里重要的是saved rip 0x7ffff7a66d20
部分。在我的CPU上,rip
是指令指针,saved rip
是“返回地址”,如pepero in this answer所述。
所以在这种情况下,停止地址是0x7ffff7a66d20
,它是main
函数的返回地址。也就是说,程序执行结束。
您可以使用英特尔的Binary Instrumentation工具'Pin'。我会避免使用模拟器进行这样一个简单的任务(模拟器通常非常慢)。 Pin可以使用模拟器执行大部分操作,无需预先修改二进制文件,也可以正常执行速度(取决于您使用的引脚工具)。
使用Pin计算指令数:
cd pin-root/source/tools/ManualExample/
make all
../../../pin -t obj-intel64/inscount0.so -- your-binary-here
inscount.out
,cat inscount.out
中的指令计数。输出将是这样的:
➜ ../../../pin -t obj-intel64/inscount0.so -- /bin/ls
buffer_linux.cpp itrace.cpp
buffer_windows.cpp little_malloc.c
countreps.cpp makefile
detach.cpp makefile.rules
divide_by_zero_unix.c malloc_mt.cpp
isampling.cpp w_malloctrace.cpp
➜ cat inscount.out
Count 716372