交流
商城
MCN
登入
注册
首页
提问
分享
讨论
建议
公告
动态
发表新帖
发表新帖
6ELF 节- .text
分享
未结
0
2662
李延
LV6
2022-07-17
悬赏:20积分
# 1. test节 .test 这里主要存放汇编代码内容。这里我们主要分析的是未链接的文件。 # 2 .text 格式 .text 存放我们所有的汇编代码。通过前面我们节头表分析的到.text 位置 ```sh Sections: Idx Name Size VMA LMA File off Algn Flags 0 .text 00000015 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE ``` 在第0x40个字节,大小一共0x15 也就是如下内容:  这样直接看字符太麻烦,我们通过objdump查看 ```sh objdump -d main.o ``` 得到 ```sh main.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <main>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: bf 00 00 00 00 mov $0x0,%edi 9: e8 00 00 00 00 callq e <main+0xe> e: b8 00 00 00 00 mov $0x0,%eax 13: 5d pop %rbp 14: c3 retq ``` main下面的内容,刚好与我们0x15个字节对应。 我们可以发现,基本上就是将汇编翻译为对应的机器语言。 下面我们分别解析。 ## 2.1. mov指令 ### 2.1.1 mov时,两个值都为寄存器 测试的汇编代码为 ```asm .globl main main: movq %rax,%rbx movq %rbx,%rcx movl %eax, %ebx movl %eax, %ecx movl %ebx, %ecx ret ``` 编译后得到对应的elf文件 ```sh 0000000000000000 <main>: 0: 48 89 c3 mov %rax,%rbx 3: 48 89 d9 mov %rbx,%rcx 6: 89 c3 mov %eax,%ebx 8: 89 c1 mov %eax,%ecx a: 89 d9 mov %ebx,%ecx c: c3 retq ``` 对于 movq 我们发现,指令占3个字节,第一个时表示movq。后面两个分别代表两个寄存器 而 movl 只占两个字节,第一个表示movl指令。 寄存器被合并在一个字节内表示。 ### 2.1.2 立即数到寄存器 ```asm .globl main main: movq $1,%rbx movq $2,%rcx movq $0xffffffffffff,%rcx movl $1, %ecx movl $2, %ecx ret ``` ```sh mov2.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <main>: 0: 48 c7 c3 01 00 00 00 mov $0x1,%rbx 7: 48 c7 c1 02 00 00 00 mov $0x2,%rcx e: 48 b9 ff ff ff ff ff movabs $0xffffffffffff,%rcx 15: ff 00 00 18: b9 01 00 00 00 mov $0x1,%ecx 1d: b9 02 00 00 00 mov $0x2,%ecx 22: c3 retq ``` 我们看到基本和寄存器一样。 ## 2.2 . 加载内存地址 ```asm .LC0: .string "movl %d\n" .LC1: .string "movl2 %d\n" .globl main main: movl $.LC0, %edi movl $.LC1, %edi ret ``` 结果: ```sh 0000000000000000 <main-0x13>: 0: 6d insl (%dx),%es:(%rdi) 1: 6f outsl %ds:(%rsi),(%dx) 2: 76 6c jbe 70 <main+0x5d> 4: 20 25 64 0a 00 6d and %ah,0x6d000a64(%rip) # 6d000a6e <main+0x6d000a5b> a: 6f outsl %ds:(%rsi),(%dx) b: 76 6c jbe 79 <main+0x66> d: 32 20 xor (%rax),%ah f: 25 .byte 0x25 10: 64 0a 00 or %fs:(%rax),%al 0000000000000013 <main>: 13: bf 00 00 00 00 mov $0x0,%edi 18: bf 00 00 00 00 mov $0x0,%edi 1d: c3 retq ``` 我们看到多了一个main-0x13 的函数,而mov的 指向的地址都为0,具体为何这样也不太清楚,后面补充。 ## # 3 变量的使用 如下示例: ```c #include <stdio.h> int main(){ printf("Hello, World!\n"); printf("Hello, World!2\n"); return 0; } ``` 这里我们主要使用了2个字符串。我们看一下这个字符串是如何定位的. ```asm 0000000000000000 <main>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: bf 00 00 00 00 mov $0x0,%edi 9: e8 00 00 00 00 callq e <main+0xe> e: bf 00 00 00 00 mov $0x0,%edi 13: e8 00 00 00 00 callq 18 <main+0x18> 18: b8 00 00 00 00 mov $0x0,%eax 1d: 5d pop %rbp 1e: c3 retq ``` ## 4 函数调用 函数调用分为两种,一个是在一个文件中的函数,一个是需要链接后的函数。 ```c int sun1(){ return 1; } int sun2(){ return 1; } int main(){ return sun1()+sun2(); } ``` 编译后.test为: ```asm 0000000000000000 <sun1>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: b8 01 00 00 00 mov $0x1,%eax 9: 5d pop %rbp a: c3 retq 000000000000000b <sun2>: b: 55 push %rbp c: 48 89 e5 mov %rsp,%rbp f: b8 01 00 00 00 mov $0x1,%eax 14: 5d pop %rbp 15: c3 retq 0000000000000016 <main>: 16: 55 push %rbp 17: 48 89 e5 mov %rsp,%rbp 1a: 53 push %rbx 1b: b8 00 00 00 00 mov $0x0,%eax 20: e8 00 00 00 00 callq 25 <main+0xf> 25: 89 c3 mov %eax,%ebx 27: b8 00 00 00 00 mov $0x0,%eax 2c: e8 00 00 00 00 callq 31 <main+0x1b> 31: 01 d8 add %ebx,%eax 33: 5b pop %rbx 34: 5d pop %rbp 35: c3 retq ```
回帖
消灭零回复
提交回复
热议榜
java 相关知识分享
8
好的程序员与不好的程序员
6
写给工程师的十条精进原则
5
spring boot以jar包运行配置的logback日志文件没生成
5
一步一步分析SpringBoot启动源码(一)
5
MockMvc测试
5
【吐槽向】是不是有个吐槽的板块比较好玩
4
logstash jdbc同步mysql多表数据到elasticsearch
3
IntelliJ IDEA 优质License Server
3
.gitignore忽略规则
3
SpringBoot启动源码分析
3
一步一步分析SpringBoot启动源码(三)
3
2
一步一步分析SpringBoot启动源码(二)
2
积分不够将无法发表新帖
2
官方产品
Meta-Boot - 基于MCN
MCN - 快速构建SpringBoot应用
微信扫码关注公众号