当前位置: 首页 > news >正文

[智能芯片] 可执行文件分析

《智能芯片》课程笔记:可执行文件分析

📋 目录

  1. 获取汇编代码与机器码
  2. 获取函数与变量的地址
  3. 分析工具使用说明
  4. 实例解析

获取汇编代码与机器码

🔧 objdump 工具简介

属性 说明
工具名称 riscv64-unknown-elf-objdump.exe
核心功能 对 ELF 可执行文件进行反汇编,提取汇编代码与机器码
适用场景 分析编译后程序的底层实现、调试、学习指令集

📌 基本使用命令

# 1. 直接在终端显示反汇编结果
riscv64-unknown-elf-objdump.exe -S example.elf# 2. 将结果重定向保存到文件(推荐)
riscv64-unknown-elf-objdump.exe -S example.elf > example.S.txt

💡 -S 选项:混合显示源代码、汇编代码和机器码,便于对照理解

📖 反汇编输出格式示例解读

image-20260314132349982

🎨 颜色/内容对照表

颜色/位置 内容类型 说明
⚫ 黑色 C源代码 原始高级语言代码
🟢 绿色 存储地址 机器码在内存中的起始地址
🔴 红色 机器码 汇编指令对应的16进制机器码
🔵 蓝色 汇编代码 编译生成的RISC-V汇编指令
⚪ 灰色 注释 编译器添加的辅助信息

获取函数与变量的地址

❓ 问题背景

上一节范例程序中定义了:

  • 变量f, s, t, p, q, a, b
  • 函数main, fun1, fun2

🎯 目标:如何获取这些符号在内存中的具体地址?


🔍 方法一:通过 .map 文件(编译时生成)

📌 前提条件

编译时需添加 -Wl,-Map=example.map 选项:

riscv64-unknown-elf-gcc.exe -march=rv32i -mabi=ilp32 -Wall -O1 -g -nostartfiles -T linker_script_onestep.ld -Wl,-Map=example.map -o example.elf startup.s fun.c main.c

📄 example.map 文件内容截取

以上一节生成的 example.map 为例。

.text           0x000000000000004c       0xdc*(.text).text          0x000000000000004c        0x0 C:\Users\*****\AppData\Local\Temp\ccXSS4dc.o.text          0x000000000000004c       0x64 C:\Users\Lenovo\AppData\Local\Temp\ccNYCzQf.o0x000000000000004c                fun10x000000000000006c                fun2.text          0x00000000000000b0       0x78 C:\Users\*****\AppData\Local\Temp\ccycWyFb.o0x00000000000000b0                main0x0000000000000128                . = ALIGN (0x4)
.data           0x0000000000000400        0xc load address 0x00000000000001280x0000000000000400                PROVIDE (_data_start = .)*(.data).data          0x0000000000000400        0x0 C:\Users\Lenovo\AppData\Local\Temp\ccXSS4dc.o.data          0x0000000000000400        0x0 C:\Users\Lenovo\AppData\Local\Temp\ccNYCzQf.o.data          0x0000000000000400        0x0 C:\Users\Lenovo\AppData\Local\Temp\ccycWyFb.o*(.sdata).sdata         0x0000000000000400        0xc C:\Users\Lenovo\AppData\Local\Temp\ccycWyFb.o0x0000000000000400                a0x0000000000000404                p0x0000000000000406                s0x0000000000000408                f0x000000000000040c                . = ALIGN (0x4)0x000000000000040c                PROVIDE (_data_end = .)0x000000000000040c                PROVIDE (_bss_start = .).bss            0x000000000000040c        0x8*(.bss).bss           0x000000000000040c        0x0 C:\Users\Lenovo\AppData\Local\Temp\ccXSS4dc.o.bss           0x000000000000040c        0x0 C:\Users\Lenovo\AppData\Local\Temp\ccNYCzQf.o.bss           0x000000000000040c        0x0 C:\Users\Lenovo\AppData\Local\Temp\ccycWyFb.o*(.sbss*).sbss          0x000000000000040c        0x4 C:\Users\Lenovo\AppData\Local\Temp\ccNYCzQf.o0x000000000000040c                b.sbss          0x0000000000000410        0x4 C:\Users\Lenovo\AppData\Local\Temp\ccycWyFb.o0x0000000000000410                q0x0000000000000412                t*(COMMON)0x0000000000000414                . = ALIGN (0x4)0x0000000000000414                PROVIDE (_bss_end = .)

📊 提取的地址信息

类型 符号 地址(16进制)
🔹 函数 fun1 0x4c
🔹 函数 fun2 0x6c
🔹 函数 main 0xb0
🔸 变量 a 0x400
🔸 变量 p 0x404
🔸 变量 s 0x406
🔸 变量 f 0x408
🔸 变量 b 0x40c
🔸 变量 q 0x410
🔸 变量 t 0x412

🔍 方法二:使用 nm 工具(分析已编译文件)

📌 使用命令

riscv64-unknown-elf-nm.exe example.elf

📄 输出示例

00000400 A __RAM_BASE
00000400 A __RAM_SIZE
00000000 A __ROM_BASE
00000400 A __ROM_SIZE
00000200 A __STACK_SIZE
00000414 B _bss_end
0000040c D _bss_start
0000040c D _data_end
00000128 T _data_lma
00000400 D _data_start
00000800 B _sp
00000000 T _start
00000400 D a
0000040c B b
00000408 D f
0000004c T fun1
0000006c T fun2
000000b0 T main
00000404 D p
00000410 B q
00000406 D s
00000412 B t

🔑 符号类型说明(第2列字母)

字母 含义 对应段
T / t 文本段(Text)函数 .text,代码区
D / d 数据段(Data)已初始化全局/静态变量 .data
B / b BSS段未初始化全局/静态变量 .bss
A 绝对地址符号,不可重定位 -
U 未定义符号(需链接时解析) -

💡 大写表示全局符号(外部可见),小写表示局部符号(文件内可见)


反汇编代码实例解析 🧪

📝 反汇编代码片段

080000a8<fun1>:
int fun1(int x, int y, float z)
{ char* p = (char*)&a; *(p+6) = 0xA9; 
80000a8: 200007b7 lui   a5,0x20000
80000ac: 00478793 addi  a5,a5,4       # a5 = &a
80000b0: fa900713 li   	a4,-87        # a4 = 0xA9
80000b4: 00e78323 sb   	a4,6(a5)      # *(p+6) = 0xA9*(p+7) = 0x42; 
80000b8: 04200713 li   	a4,66         # a4 = 0x42
80000bc: 00e783a3 sb   	a4,7(a5)      # *(p+7) = 0x42return y; 
80000c0: 00058513 mv   	a0,a1         # 返回值 = y
80000c4: 00008067 ret                 # 函数返回
}

❓ 问题与解答

问题 解答 分析过程
(1) fun1函数地址? 0x80000a8 函数标签 <fun1> 后的起始地址
(2) 机器码占用字节数? 32 Bytes 0x80000c7 - 0x80000a8 + 1 = 31+1 = 32
(3) 地址 0x80000ae 存储值? 0x47 机器码 00478793 小端存储:[ac]=93, [ad]=87, [ae]=47, [af]=00
(4) *(p+7)=0x42 实现方式? 2条汇编指令,8字节机器码 li a4,66 (4B) + sb a4,7(a5) (4B)

🔍 小端模式(Little-Endian)存储示意

机器码:00478793(32位,16进制)内存地址(低→高):  80000ac  80000ad  80000ae  80000af
存储内容(16进制):   93       87       47       00↑低字节                    ↑高字节

💡 RISC-V 采用小端模式:低字节存低地址,高字节存高地址


拓展:分析工具使用说明 🛠️

📦 Binutils 工具集概览

工具 功能 常用场景
objdump 反汇编、查看段信息 分析机器码与汇编对应关系
nm 列出符号表 查找函数/变量地址
size 显示各段大小 分析程序内存占用
objcopy 格式转换、提取段 生成bin/hex文件用于烧录
readelf 解析ELF文件结构 深入理解可执行文件格式

🔎 查看工具帮助信息

# 通用方法:添加 --help 参数
riscv64-unknown-elf-objdump.exe --help
riscv64-unknown-elf-nm.exe --help# 查看特定选项说明
riscv64-unknown-elf-objdump.exe --help | grep -i "disassemble"

🎯 常用组合命令示例

# 1. 反汇编并过滤特定函数
riscv64-unknown-elf-objdump -S example.elf | grep -A 20 "<fun1>:"# 2. 查看所有全局符号地址
riscv64-unknown-elf-nm -g example.elf# 3. 查看程序各段大小
riscv64-unknown-elf-size example.elf
# 输出:text    data     bss     dec     hex filename
#      1234     567      89    1890     762 example.elf# 4. 提取纯机器码(二进制格式)
riscv64-unknown-elf-objcopy -O binary example.elf example.bin

笔记整理基于《智能芯片》课程课件,适用于《智能芯片》课程学习参考 🚀

📚 主讲人:柳星

📧 邮箱:liu.xing@whut.edu.cn

🎯 课程核心:理解可执行文件的内部结构与分析方法

http://www.jsqmd.com/news/476977/

相关文章:

  • MaoTai_GUIT常见问题解决:网络异常、登录失败、抢购无反应处理方案
  • PyCaret模型部署到GCP:从训练到Cloud Function的完整指南
  • NEURAL MASK惊艳效果展示:婚纱边角与细碎发丝剥离作品集
  • idea的使用和新建项目
  • Guanaco模型的可扩展性:从7B到65B的QLoRA微调经验
  • 聊聊2026年全国靠谱的化学试剂生产厂,化学试剂购买推荐 - mypinpai
  • DAMOYOLO-S快速验证:10分钟完成从镜像拉取到首张图片检测全流程
  • 单通道语音分离终极指南:Awesome Speech Enhancement项目核心算法与实现
  • 襄阳红酒包装盒加工价格,创意包装盒源头工厂靠谱吗 - 工业推荐榜
  • 如何快速创建PyCaret机器学习模型的REST API:MLflow集成指南
  • Neeshck-Z-lmage_LYX_v2惊艳案例:‘赛博朋克雨夜东京’提示词生成动态氛围图
  • 如何用 heatmap.js 快速实现惊艳的网页热图可视化?终极简单教程
  • DeEAR效果验证:临床抑郁症患者语音样本在DeEAR自然度维度的统计学显著下降
  • 2026年性价比高的白蚁防治公司盘点,讲讲广澜白蚁防治的安全性如何 - myqiye
  • 细聊靠谱的四害消杀品牌,广澜科技排名如何 - 工业品网
  • Stanford Alpaca权重恢复教程:从LLaMA到Alpaca的完整转换方案
  • Pure-Live-Core核心功能解析:打造无缝直播体验
  • UI-TARS-desktop案例集锦:Qwen3-4B在客服工单处理、代码辅助、文档校对三大场景的真实效果
  • OpenBMC与Yocto Project集成:构建嵌入式Linux系统的最佳实践
  • Windows版本无缝转换:CMWTAT_Digital_Edition多版本激活与升级教程
  • 2026年职业院校技能大赛中职移动应用与开发模块二10套题库开发培训视频(全套)
  • 2026年最新瑞祥卡回收趋势与实用技巧 - 团团收购物卡回收
  • SP2878 KNIGHTS - Knights of the Round Table 题解
  • Qwen3-Reranker-0.6B效果展示:RAG检索精排前后对比图+真实得分可视化
  • pydata-book示例代码库:100+个数据分析实用代码片段
  • 2026年职业院校技能大赛中职移动应用与开发模块二智慧党建系统零基础培训视频(全套)
  • 【Physics】1. Two Blocks and a Pulley、Sliding Off a Sphere
  • RMBG-2.0镜像免配置教程:Docker一键拉取+开箱即用抠图终端
  • 那些被遗忘的卡券价值,中银通支付卡回收隐藏的秘密 - 京顺回收
  • 大模型落地指南:小白程序员必看,收藏这份从入门到实战的学习资料!