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. ...
随机推荐
- Spring Boot自动装配
前言 一些朋友问我怎么读源码,这篇文章结合我看源码时候一些思路给大家聊聊,我主要从这三个方向出发: 确定目标,这个目标要是一个具体,不要一上来我要看懂Spring,这是不可能的,目标要这么来定,比如看 ...
- php变量中两种特殊类型
第一种----资源 资源(resource):资源是由专门的函数来建立和使用的,例如打开文件.数据连接.图形画布.我们可以对资源进行操作(创建.使用和释放).任何资源,在不需要的时候应该被及时释放.如 ...
- 创建一个区域(Creating an Area) |使用区域 | 高级路由特性 | 精通ASP-NET-MVC-5-弗瑞曼
摘自:http://www.cnblogs.com/chenboyi081/p/4472709.html#tar2015050302 下面的AdminAreaRegistration继承自AreaRe ...
- c#数字图像处理(六)直方图均衡化
直方图均衡化又称直方图修平,是一种很重要的非线性点运算.使用该方法可以加强图像的局部对比度,尤其是当图像的有用数据的对比度相当接近的时候.通过这种方法,亮度可以更好的在直方图上分布. 直方图均衡化的基 ...
- Python单元测试unittest测试框架
本文的主题是自动化测试框架的实现,在实现之前,先了解一下关于unittest模块的相关知识: Python中有一个自带的单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回 ...
- ios--->const 用法总结
const 用法总结 宏.变量.常量区分 宏:只是在预处理器里进行文本替换,没有类型,不做任何类型检查,编译器可以对相同的字符串进行优化.只保存一份到 .rodata 段.甚至有相同后缀的字符串也可以 ...
- JDK源码之Integer类分析
一 简介 Integer是int基本类型的包装类,同样继承了Number类,实现了Comparable接口,String类中的一些转化方法就使用了Integer类中的一些API,且fianl修饰不可继 ...
- 一文教你一次性完成Helm 3迁移
2019年,Kubernetes软件包管理器--Helm发布了最新版本Helm 3,并且该版本已经stable.Helm 3中的一些关键特性我们在之前的文章中已经介绍过,其中一些功能吸引了许多开发人员 ...
- 024.Python模块OS模块
一 OS模块 对系统进行操作 1.1 popen 可以把运行的结果,这个字符串转化成utf-8这样的编码格式在进行输出 import os res = os.popen("ifconfig& ...
- 微信小程序框架分析小练手(一)——猫眼电影底部标签导航制作
旧版猫眼电影底部有4个标签导航:电影.影院.发现.我的,如下图所示: 一.首先,打开微信开发者工具,新建一个项目:movie.如下图: 二.建立如下的一些目录: 三.将底部标签导航图标的素材放到ima ...