C语言程序转汇编代码
最近在学着写bootloader,由于汇编太繁杂,希望可以使用C语言完成一部分,然后转成NASM汇编代码,经过摸索,最终找到了一个解决方案,记录于此,留作参考。
核心步骤
使用gcc编译得到.o文件
这一步需要加上一些参数对编译行为进行控制。具体自行参考gcc文档。
我最终使用的命令参数为
shell gcc -fno-pic -fno-asynchronous-unwind-tables -m32 -O2 -s -c -o $@ $<
具体含义我也没有深入了解,-m32是生成32位代码,-O2是一种优化级别,-fno-pic似乎是必要,要不然每个文件最终都会生成一个额外的函数。使用objconv程序将.o文件转换成汇编代码
objconv -fnasm $<
objconv可以将.o文件转成多种形式的汇编,具体自行查阅,上面的参数是要转成NASM代码。
问题
还有一个问题是,这样直接转换成的汇编代码包含多个段,以及各种对齐指令,以及enbdrXX指令,需要自己根据需要进行删减。
我所做的是只保留.text段,并删减对齐指令、enbdrXX指令。
我的需求及实现
最终我需要的是将使用C语言完成的函数转换成汇编形式的函数,并去掉编译器相关、对齐相关的一些代码。我的Makefile如下。
all : $(subst .c,.func,$(wildcard *.c))
%.func : %.asm
./extractFunc.py $<
%.asm : %.o
./objconv -fnasm $<
%.o : %.c
gcc -fno-pic -fno-asynchronous-unwind-tables -m32 -O2 -s -c -o $@ $<
clean :
rm -rf *.asm *.o *.func
其功能是将当前目录中的所有C语言文件转换成NASM汇编语言文件。
C函数文件示例:
//filename : stripe.c
#define DISPLAY_MEMORY_BASE 0xa0000
#define WIDTH 320
#define HEIGHT 200
void stripe()
{
for (int i = DISPLAY_MEMORY_BASE; i <= DISPLAY_MEMORY_BASE+WIDTH*HEIGHT/2; i++)
{
*((int *)i) = (0b11111100 & i);
}
}
使用make命令得到的结果如下:
; filename : stripe.func
stripe: ; Function begin
mov eax, 655360 ; 0004 _ B8, 000A0000
; Filling space: 7H
; Filler type: lea with same source and destination
; db 8DH, 0B4H, 26H, 00H, 00H, 00H, 00H
?_001: mov edx, eax ; 0010 _ 89. C2
add eax, 1 ; 0012 _ 83. C0, 01
and edx, 0FCH ; 0015 _ 81. E2, 000000FC
mov dword [eax-1H], edx ; 001B _ 89. 50, FF
cmp eax, 687361 ; 001E _ 3D, 000A7D01
jnz ?_001 ; 0023 _ 75, EB
ret ; 0025 _ C3
; stripe End of function
gcc和objconv已经在前面提到过了,那个python脚本的作用删掉一些我所不需要的代码,只保留.text部分,并删除其中的对齐指令和enbdrXX指令。内容如下:
#!/usr/bin/python3
#filename : extractFunc.py
import os
import sys
def extractFunc(filename):
fin = open(filename)
lines = fin.readlines()
start = 0
end = 0
lineNum = -1
for line in lines:
lineNum += 1
if line.startswith(f'SECTION .text'):
start = lineNum + 1
continue
if line.startswith(f'SECTION .data'):
end = lineNum
break
funcLines = lines[start:end]
cleanFuncLines = []
for line in funcLines:
if line.startswith(' endbr32') or line.startswith('ALIGN'):
continue
cleanFuncLines.append(line)
fout = open(f'{filename[:-4]}.func', 'w')
fout.writelines(cleanFuncLines)
print(filename)
if __name__ == '__main__':
extractFunc(sys.argv[1])
参考链接
- https://stackoverflow.com/questions/20737947/how-to-generate-a-nasm-compilable-assembly-code-from-c-source-code-on-linux
- https://stackoverflow.com/questions/1647359/is-there-a-way-to-get-gcc-to-output-raw-binary
C语言程序转汇编代码的更多相关文章
- 分析一个C语言程序生成的汇编代码-《Linux内核分析》Week1作业
署名信息 郭春阳 原创作品转载请注明出处 :<Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 C源码 这 ...
- 解析c语言背后的汇编代码
源码 很简单的c语言代码,作用是交换两个数: #include <stdio.h> void swap(int * a, int * b) { *a = *a + *b - (*b = * ...
- 一个简单C程序的汇编代码分析
几个重要的寄存器 eip - 用于存放当前所执行的指令地址 esp - 栈(顶)指针寄存器 ebp - 基址(栈底)指针寄存器 简单的C程序 int g(int x) { ; } int f(int ...
- 从C简单程序的汇编代码入手,以理解计算机工作原理。
贺邦 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000#/info 知识准备 ...
- 如何在Visual Studio里面查看程序的汇编代码?
开发工具:Visual Studio 2015 1,在源代码中设置至少一个断点,目的让我们进入调试模式. 2,启动调试,当程序进入调试模式,停留在我们设定的断点处时候,使用快捷键"ALT+8 ...
- 如何在Delphi里面查看程序的汇编代码?
开发工具:Delphi 10 Update2 1,在源代码中设置至少一个断点,目的让我们进入调试模式. 2,启动调试,当程序进入调试模式,停留在我们设定的断点处时候,使用快捷键"CTRL+A ...
- 通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
秦鼎涛 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验一 通过汇编一个简单的C程序,分析汇编代码 ...
- Ubuntu16.04 中 Vscode 如何断点调试C语言程序
个人博客链接:Ubuntu16.04 中 Vscode 如何断点调试C语言程序 问题:环境是 Ubuntu16.04,如何使用 Vscode 断点调试C语言程序. 写代码没有调试环境是不能忍受的,所以 ...
- 《Linux内核分析》week1作业-分析一个简单c语言的汇编代码
1.C语言源码 #include <stdio.h> int g(int x){ ; } int f(int x){ return g(x); } int main(){ )+; } 2. ...
随机推荐
- 如何高效实用 Git
Git 工作流 只要项目是多人参与的,那么就需要使用正确的 Git 工作流程. 下面介绍一个简单有效的工作流程. 场景 假设有一个项目,要开发下一代的 Facebook,你就是这个项目的技术 lead ...
- 深入学习MySQL 03 Schema与数据类型优化
Schema是什么鬼 schema就是数据库对象的集合,这个集合包含了各种对象如:表.视图.存储过程.索引等.为了区分不同的集合,就需要给不同的集合起不同的名字,默认情况下一个用户对应一个集合,用户的 ...
- 制作一个类“全能扫描王”的简易扫描软件(opencv)
相信很多人手机里都装了个“扫描全能王”APP,平时可以用它来可以扫描一些证件.文本,确实很好用,第一次用的时候确实感觉功能很强大啊算法很牛逼啊.但是仔细一想,其实这些实现起来也是很简单的,我想了下,实 ...
- 一个低级shell简易学生信息管理系统-新增登陆注册功能
还有bug 不修改了 小声bb一下 这玩意真的要控制版本 随手保存 本来有个超完整的版本 一开心被我rm - f 了 后续还出现了 更多的bug 仔细仔细 源码如下: record=stu.db if ...
- 异想家Win10系统安装的软件与配置
1.C盘推荐一个硬盘,256G,安装好驱动,显卡配置好高性能,激活Win10,屏蔽WIn10驱动更新(Show or hide updates.diagcab),改电脑名称为Sandeepin-PC. ...
- 自学前端开发,现在手握大厂offer,我的故事还在继续
简要背景 我是一个非科班出身的程序员,而且是连续跨专业者,用一句话总结就是:16 届本科学完物流,保送研究生转交通,自学前端开发的休学创业者. 17 年休学创业,正式开始学习前端,离开创业公司后,我又 ...
- ROS之服务
服务(service)是另一种在节点之间传递数据的方法,服务其实就是同步的跨进程函数调用,它能够让一个节点调用运行在另一个节点中的函数. 我们就像之前消息类型一样定义这个函数的输入/输出.服务端(提供 ...
- 微信小程序框架分析小练手(三)——仿香哈菜谱小程序制作
香哈菜谱是一款围绕美食而成的小程序,在这里可以查看各式各样的菜谱. 一.打开微信开发者工具,新建一个项目:xhcp.如下图: 二.建立如下的一些目录: 三.将底部标签导航图标.美食轮播图片.宫格导航图 ...
- python学习--curl
PyCurl是一个C语言写的libcurl的python绑定库.libcurl 是一个自由的,并且容易使用的用在客户端的 URL 传输库.它的功能很强大,PycURL 是一个非常快速(参考多并发操作) ...
- PostMan向企业微信机器人传送数据测试
1 在企业微信中创建机器人 获取:webhook 地址 2.在Postman软件中创建Post文件 Post文件请求类型要与机器人所接受的类型一致.Get 或者 Post Url地址为上面webh ...