由于在下水平相当有限,不当之处,还望大家批评指正^_^
以文件haha.S的内容及其编译后生成的内容,我们可以得出一些知识点。
(haha.S是从内核源码中搞了点x86汇编代码出来,然后改了改得到的):
[root@ovs_test_smb test]# cat haha.S
#define ALIGN .align 4,0x90
#define ENTRY(name) \
.globl name; \
ALIGN; \
name:
movl %eax, %ds
ENTRY(global_symbol)
movl %eax, %ss
call f1
ENTRY(sys_call_table)
.long 1
.long 2
.long 0xffffffff
.section .test.sec
movl %eax, %es
从编译后的结果,能看出一些规律:
1. 源文件开头没有明确生成的内容属于哪个section,但汇编器默认将他放到了.text节
2. 节中如果有符号,但节的开头没有定义为符号,汇编器会自动为节的开头生成一个符号。名字是“节中首个符号名-首个符号的偏移量”。
3. 如果一个节中没有符号,则汇编器会在节的开头定义一个符号,符号名就是节名。例如 .test.sec节就是
4. 对于elf文件中的各个节及符号的内容,汇编器并不分区哪个是代码,哪个是数据。至于节名中的text或data等字样,那只是对用户有标记提示意义。节里面的内容,到底是代码,还是数据,只能根据相应的指令执行时的含义来看。况且,节名也是用户可以随便取的。例如:a.b.c.d
5. 汇编代码访问外部符号,直接通过名字访问即可。无须像C语言那样extern一下。例如haha.S中call f1函数调用。
6. objdump反汇编工具,对于任何节的内容,一方面显示出其内容,同时尝试解释出对应的指令。此工具的作用与汇编器相反,但风格相似,即都认为任何节的内容都有可能是代码,也有可能是数据。
[root@ovs_test_smb test]# gcc -c haha.S
[root@ovs_test_smb test]# objdump -D haha.o
haha.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <global_symbol-0x4>:
0: 8e d8 mov %eax,%ds
2: 66 90 xchg %ax,%ax
0000000000000004 <global_symbol>:
4: 8e d0 mov %eax,%ss
6: e8 00 00 00 00 callq b <global_symbol+0x7>
b: 90 nop
000000000000000c <sys_call_table>:
c: 01 00 add %eax,(%rax)
e: 00 00 add %al,(%rax)
10: 02 00 add (%rax),%al
12: 00 00 add %al,(%rax)
14: ff (bad)
15: ff (bad)
16: ff (bad)
17: ff .byte 0xff
Disassembly of section .test.sec:
0000000000000000 <.test.sec>:
0: 8e c0 mov %eax,%es