我理解程序集和C代码。 我有以下C程序,编译后只生成Object文件。
#include <stdio.h>
int main()
{
int i = 10;
int j = 22 + i;
return 0;
}
我执行了以下命令
objdump -S myprogram.o
以上命令的输出为:
objdump -S testelf.o
testelf.o: file format elf32-i386
Disassembly of section .text:
00000000 <main>:
#include <stdio.h>
int main()
{
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 10 sub $0x10,%esp
int i = 10;
6: c7 45 f8 0a 00 00 00 movl $0xa,-0x8(%ebp)
int j = 22 + i;
d: 8b 45 f8 mov -0x8(%ebp),%eax
10: 83 c0 16 add $0x16,%eax
13: 89 45 fc mov %eax,-0x4(%ebp)
return 0;
16: b8 00 00 00 00 mov $0x0,%eax
}
1b: c9 leave
1c: c3 ret
助记符命令之前的数字数字是什么意思 即&#34; 83 ec 10&#34;之前&#34; sub&#34;命令或 &#34; c7 45 f8 0a 00 00 00&#34;之前&#34; movl&#34;命令
我使用以下平台编译此代码:
$ lscpu
Architecture: i686
CPU op-mode(s): 32-bit
Byte Order: Little Endian
CPU(s): 1
On-line CPU(s) list: 0
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 1
Vendor ID: GenuineIntel
答案 0 :(得分:1)
这些是x86操作码。除上述评论中列出的参考之外,还提供了详细的参考资料here。
例如,c7 45 f8 0a 00 00 00
之前的movl $0xa,-0x8(%ebp)
是操作码字节的十六进制值。它们告诉CPU将10十进制的立即值(作为4字节值)移动到位于堆栈帧基指针上方8字节的当前堆栈中的地址。这就是代码运行时C源代码中的变量i
所在的位置。堆栈顶部的内存地址低于堆栈底部,因此从底座向负方向移动会向上移动堆栈。
c7 45 f8
操作码意味着移动数据并清除EFLAGS寄存器中的算术进位标志。有关详细信息,请参阅reference。
其余代码为immediate value。由于您使用的是小端系统,因此首先列出数字的最低有效字节,这样10十进制(十六进制为0x0a,4字节值为0x0000000a)存储为0a 00 00 00
。