阅读正在执行的指令

时间:2010-01-10 19:29:34

标签: c assembly machine-code

正如标题所示,有没有办法在执行后读取机器代码指令?例如,如果我有一个任意的C代码块,并且我想知道在输入该块时编译和执行了哪些指令,那么有没有办法做到这一点?提前感谢您对该主题的任何指示。

编辑:关于我正在尝试做什么的一些动机:我想要一个程序,大致计算出它是如何编译的,或者它当前正在运行的指令而不需要知道如何制作机器代码。即我想使用一些编译器以前在编译程序时所做的艰苦工作,以便我可以复制并稍后使用正在执行的机器代码。

5 个答案:

答案 0 :(得分:2)

鲜为人知的事实:GDB内置了一个curses接口。

使用gdbtuigdb Ctrl + X Ctrl + A 输入,然后 Ctrl + X 2 开始一起显示汇编和源。当前指令突出显示,您可以使用箭头键进行导航。

答案 1 :(得分:1)

我不知道你是否要求在运行时这样做,或者你想要查看包含已编译C代码的汇编代码的文本文件。

如果是前者,只需使用调试器(在gdb中使用gcc进行反汇编,或使用Microsoft Visual Studio中的集成调试器)。

如果是后者,则必须查找编译器的特定命令。例如,使用Visual Studio,只需使用标志/FAs;这将使用您的源代码输出汇编代码。对于gcc

gcc -c -g -Wa,-a,-ad foo.c > foo.lst

答案 2 :(得分:1)

几乎每个调试器都可以做到这一点。

对于gdb,要记住的有用技巧是:display/i $pc

执行一次,然后在函数上设置断点,使用stepinexti逐步执行该函数。

每次都会自动显示PC上的指令。

Ross-Harveys-MacBook-Pro:so ross$ cat > deb.c
int main(void) { return (long)main + 0x123; }
Ross-Harveys-MacBook-Pro:so ross$ cc -O deb.c
Ross-Harveys-MacBook-Pro:so ross$ gdb -q a.out
Reading symbols for shared libraries .. done
(gdb) break main
Breakpoint 1 at 0x100000f30
(gdb) display/i $pc
(gdb) r
Starting program: /Users/ross/so/a.out 
Reading symbols for shared libraries +. done

Breakpoint 1, 0x0000000100000f30 in main ()
1: x/i $pc  0x100000f30 <main+4>:   lea    -0xb(%rip),%rax        # 0x100000f2c <main>
(gdb) stepi
0x0000000100000f37 in main ()
1: x/i $pc  0x100000f37 <main+11>:  add    $0x123,%eax
(gdb) stepi
0x0000000100000f3c in main ()
1: x/i $pc  0x100000f3c <main+16>:  leaveq 

答案 3 :(得分:0)

大多数调试器都有选项来查看正在执行的代码的反汇编。

Ex:在gdb中使用反汇编命令。

答案 4 :(得分:0)

如果你想知道特定功能的执行路径是什么,也许某些处理器具有这样的功能,但通常没有。现在你可以做的是在模拟器中运行并修改模拟器以打印出读取或读取的地址或其他任何内容。

如果这只是一个使用gcc / binutils工具的反汇编问题objdump -D filename&gt; out.list并且不打扰执行或使用调试器