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. ...
随机推荐
- mysql 注入问题
1.实质 MySql语句是用户自行拼接的字符串 2.例子 import pymysql # 获取用户输入信息 username = input("请输入用户名:") pwd = i ...
- Java电商支付系统实战(一)- 简介
现如今,支付成为热点 对于电商业务,这都是不可或缺的 核心功能剖析 下单->支付 nginx 将用户请求反向代理到我们编写的电商系统 = 下单 之后,点击支付跳转到支付系统,最后对接 通过跳转将 ...
- Java入门 - 语言基础 - 12.Number和Math类
原文地址:http://www.work100.net/training/java-number-math.html 更多教程:光束云 - 免费课程 Number和Math类 序号 文内章节 视频 1 ...
- python类属性和实例属性(类变量和实例变量)
在类中,根据变量定义的位置不同,以及定义的方式不同,类属性又可以细分为以下三种类型: 类体中,所有函数之外:类属性(类变量) 类体中,所有函数内部,以"self.变量名"的方式定义 ...
- 公司项目redis 项目报错 记事
异常内容: Timeout performing GET Key_CacheHSCode, inst: 1, mgr: ExecuteSelect, err: never, queue: 2, qu ...
- java面试| 精选基础题(3)
每天进步一点点,距离大腿又近一步! 阅读本文大概需要6分钟 系列文章 java面试| 精选基础题(1) java面试|精选基础题(2) 1.float f=3.4;是否正确? 答:不正确,编译无法通过 ...
- Quantitative Trading with R(一):两个简单的策略
下面是两个使用R中的Quantstrat包进行策略构建的例子,都是对600550.ss.600192.ss.600152.ss.600644.ss.600885.ss.600151.ss六只股票进行投 ...
- tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows
缩点练习 洛谷 P3387 [模板]缩点 缩点 解题思路: 都说是模板了...先缩点把有环图转换成DAG 然后拓扑排序即可 #include <bits/stdc++.h> using n ...
- shiro中ecache-core版本引起的异常
ecache-core包版本不对引起的错误,将2.5.3换成2.4.5就好了 来源 WARN [RMI TCP Connection(3)-127.0.0.1] - Exception encount ...
- 虚拟机ubuntu系统怎么添加 VMware tools
首先弹出光盘 然后安装 点击安装VMware tools 然后进入光盘 打开VMware tools 文件夹 将解压文件拉到桌面上 打开桌面上的文件夹 不选中文件 然后键入下面的内容 输入密码 输入y ...