- 博客(19)
- 资源 (1)
- 收藏
- 关注
原创 理解链接器
C语言和汇编语言相互调用不同的语言就像一座孤岛,似乎毫不相干,但是所有的代码最终都要编译成机器指令,他们本质上也是一样的,最终都是变成指令给CPU下达命令。1. C语言的链接过程我们知道一个C语言源文件变成可执行文件,需要经过一下几个步骤: 预处理。(hello.c -> hello.i)把头文件包含起来。 编译。(hello.i -> hello.s)编译成汇编代码。 汇编。(hello.s -> hello.o)生成目标文件。 链接。(h
2024-09-18 19:27:56 755
原创 使用rust自制操作系统内核
本操作系统是一个使用rust语言实现,基于32位的x86CPU的分时操作系统。GitHub - CaoGaorong/os-in-rust: 使用rust实现一个操作系统内核如下图是该项目的文件结构:下面我挑几个重点的模块介绍:模块名称模块类型模块介绍buildmakefile生成make之后生成的文件cat用户程序(独立进程)(写入到文件系统,然后shell可以加载成为一个进程运行)自制的cat程序,把文件系统中的文本文件内容输出到控制台echo。
2024-09-18 14:28:37 2122
原创 Linux系统中链表的骚操作
文章目录Linux系统内核队列的骚操作一、常规链表的实现二、Linux中的链表实现1. 链表节点的结构2. 数据节点3. 通过结构体成员访问结构体自身3.1 计算结构体成员的偏移量3.2 得到结构体本身的地址4. 组成链表Linux系统内核队列的骚操作本系统仿照Linux中的队列实现是一个双向链表,个人认为Linux中的双向链表实现简直太妙了。一、常规链表的实现在学习数据结构课程时,都学过双向链表这种数据结构,基本上都是下面这种结构:struct student { struct stud
2021-06-21 14:49:42 346
原创 为什么文件描述符是一个数字?
文章目录为什么文件描述符是一个数字?1. 如何描述磁盘中的文件2. 如何描述一个打开的文件3. 文件描述符4. 文件描述符和文件的联系为什么文件描述符是一个数字?如果使用系统调用函数open打开一个文件会得到一个文件描述符,可是为什么文件描述符是一个数字呢?凭借这个数字怎样定位到一个文件的呢?文件描述符只是一个数字,不同的进程使用相同的文件描述符不会冲突吗?在说清楚为什么文件描述符是数字之前,要先说一下几点:磁盘中的文件如何描述如何描述一个打开的文件1. 如何描述磁盘中的文件对于一个文件
2021-06-21 14:47:10 580
原创 <__x86.get_pc_thunk.ax>有什么作用?
一、<__x86.get_pc_thunk.ax>在把C语言反汇编时,经常会看到这样的代码<__x86.get_pc_thunk.ax>。比如下面一段C语言代码:// main.cint main(void){ return 0;}然后,生成32位的可执行文件(32位的可执行文件比较简单,容易分析):gcc main.c -o main -m32然后反汇编,我这里使用gdb反汇编(也可以使用objdump等其他工具):可以看到main函数的反汇编结果。其他
2021-06-11 21:59:50 3208 1
原创 主函数main和程序入口_start
主函数main和程序入口_start众所周知,C程序的入口并不是main函数,而是_start函数,只不过gcc链接器默认会依赖一些库,然后_start会调用main。那么_start做了什么呢?调用关系是怎样的?一、概括下图是Linux中一个可执行程序执行时,各个模块的调用情况:这张图几乎包含了,一个程序,从加载到执行的所有过程,注意,main函数的位置。只有main函数部分是可以自己写的,其余部分都是加载器干的。二、具体分析想具体分析,可以写一个C程序然后反汇编,查看汇编代码。但是,
2021-06-11 21:58:27 3807 1
原创 为什么写C程序在结束时不需要系统调用exit?
为什么写C程序在结束时不需要系统调用exit?一、系统调用exit众所周知,一个程序的执行和结束,都是需要发起系统调用。调用execve系统调用,让操作系统加载该程序,调用exit系统调用,表示程序要退出,让操作系统清理空间。写过汇编语言的都知道,一般都会使用下面的语句来(以Intel汇编为例)发起系统调用exit:mov eax,1int 0x80这是发起系统调用exit,用于程序退出。但是,在C语言中,却没有这样系统调用退出的代码。?你说这个东西太偏了,没用?接着看下面的代码。二
2021-06-11 21:56:58 427 1
原创 C语言调用函数时参数是使用栈还是寄存器
文章目录一、结论二、验证1. 32位程序2. 64位程序2.1 参数小于等于6个2.2 参数大于6个一、结论网上的文章有的说C语言调用函数参数使用栈传递,有的说使用寄存器传递。那么到底参数是使用栈还是寄存器呢?先说结论:32位程序使用栈传递64位程序根据参数的个数而不同参数1~6个,使用寄存器传递参数大于6个,多出来的参数使用栈传递二、验证1. 32位程序源代码:// main.cvoid fun(int a, int b){ a += 1; b +=
2021-05-29 17:12:38 3136
原创 gocv.Mat类型和image.Image互相转化
gocv中的Mat类型图像转换成image.Image类型,代码如下:/* Parameters: mat: gocv.Mat,原图像 format: string,要转换的类型格式,比如.png .jpeg Returns: img: image.Image 转换之后的图像 err: error*/func cvtMatToImage(mat gocv.Mat, format string) (img image.Image, err error) { // 把mat转成字节,
2021-04-26 12:46:13 2519
原创 Go语言如何在图片上添加中文
文章目录1. 效果展示2. 实现代码2.1 参数说明3. 效果测试3.1 改变字体大小3.2 改变颜色4. 参考资料1. 效果展示下面是原图:下面是添加了文字的图片:2. 实现代码我把给图片添加文字的代码封装到了一个函数addLabel里面,具体代码如下:func addLabel(img image.Image, label string, x, y int, color *image.Uniform, size float64, fontPath string) (image.Image
2021-04-26 12:21:44 1801 3
原创 IPv6地址、单播、多播/组播介绍
IPv6地址、单播、多播/组播介绍1. IPv6地址介绍这里主要介绍IPv6地址,什么是IP地址就不介绍了。IPv6地址主要是为了解决IPv4地址枯竭的问题。1.1 IPv6地址的格式IPv6地址有128位,通常使用16进制表示,一个16进制数可以表示4位二进制,因此128位可以使用32个16进制数表示,而把4个16进制数又分成一组,因此128位可以表示成8组。如下图所示,一个X表示一组(4个)16进制字符串,也就是一组包含了16个二进制。一共有8组。图片来源:《IPv6 Fundament
2021-04-17 17:30:20 19863 2
原创 Ebiten Go语言GUI编程
Go语言GUI编程包-Ebiten文章目录Go语言GUI编程包-Ebiten1. 前言2. Ebiten库介绍3. Ebiten在窗口显示文字4. Ebiten在窗口显示图片4.1 直接展示图片4.1 指定位置展示图片5. Ebiten监听鼠标事件6. 其他1. 前言最近碰到一个题目,就是鼠标选择图片区域,然后把选中的区域进行图像处理,图像处理好说,调用opencv的库函数即可,关键是如何用鼠标选择图片区域,这就涉及到GUI编程了,因此我去了解一下如何使用Go语言的GUI编程。Go语言没有官方GUI
2021-04-17 15:38:41 1653
原创 [机器视觉]gocv图像水平投影和垂直投影
文章目录1. 水平投影和垂直投影2. 投影原理3. 代码实现1. 水平投影和垂直投影图像水平投影和垂直投影效果如下图所示:原图:水平投影:垂直投影:2. 投影原理投影原理很简单,比如水平投影,就是水平方向,把每一行的像素累加起来,然后绘制成图像。垂直投影就是,垂直方向,把每一列的像素累加起来,然后绘制成图像。投影的感觉有点像就是把图片水平方向或者垂直方向压缩了一样。3. 代码实现代码实现就是先把图像转成数组,然后遍历数组,如果是水平投影,需要计算每一行的像素累加,如果是垂直投影,
2021-04-06 18:39:49 3813
原创 gocv截取图片的部分
gocv截取图片C++的opencv库是可以直接截取某个图片的部分的,比如:Mat src = imread("image.png");Rect crop(1, 1, 64, 67);Mat rez = src(crop);如上代码,读取image.png并截取其中的矩形部分。但是gocv中的Mat并没有像C++那样的构造方法,传入一个矩形Rect就可以构造一个Mat。Google了一下,发现Github上面有人提了issue,正是我想要的答案:https://github.com/hybr
2021-04-06 18:26:35 1333
原创 C语言和汇编语言相互调用
C语言和汇编语言相互调用不同的语言就像一座孤岛,似乎毫不相干,但是所有的代码最终都要编译成机器指令,他们本质上也是一样的,最终都是变成指令给CPU下达命令。1. C语言的链接过程我们知道一个C语言源文件变成可执行文件,需要经过一下几个步骤:预处理。(hello.c -> hello.i)把头文件包含起来。编译。(hello.i -> hello.s)编译成汇编代码。汇编。(hello.s -> hello.o)生成目标文件。链接。(hello.o ->
2021-03-29 11:11:17 10568 7
原创 gdb调试查看CALL指令的压栈情况
gdb调试查看CALL指令的压栈情况文章目录gdb调试查看CALL指令的压栈情况CALL指令时压栈使用gdb调试验证CALL指令压栈情况查看_start标号断点执行前的情况查看反汇编代码查看print标号断点执行前的情况查看栈段的内容结论CALL指令时压栈有这样一段代码,功能是输出字符串,代码如下:section .datastrHello db "Hello World!", 0AhSTRLEN equ $-strHellosection .textglobal _start_sta
2021-03-18 11:03:25 1445
原创 NASM汇编发起系统调用输出Hello World
NASM汇编发起系统调用输出Hello World文章目录NASM汇编发起系统调用输出Hello World1. 汇编程序输出Hello World的4种方式2. 汇编发起Linux系统调用2.1 发起系统调用的步骤2.2 系统调用号对应表2.3 发起系统调用输出Hello, World2.4 更多代码练习1. 汇编程序输出Hello World的4种方式向显存中直接写入数据调用DOS中断调用BIOS中断发起系统调用(System Call)对于第一种方式,直接操作显存,进程应该是不允许直
2021-03-18 10:53:25 1218
原创 【机器视觉】gocv均值滤波、中值滤波、高斯边缘检测
文章目录1. 用到的API2. 效果展示3. 完整代码:1. 用到的API功能用到的API图片添加文字gocv.PutText()均值滤波gocv.Blur()中值滤波gocv.MedianBlur()高斯滤波gocv.GaussianBlur()高斯边缘检测gocv.Laplacian()详细的用法可以查看官方文档:https://pkg.go.dev/gocv.io/x/gocv#section-documentation2. 效果展示
2021-03-15 10:39:13 849
原创 【机器视觉】gocv阈值分割、图像按位反色、提取图像边缘
文章目录1. 用到的API2. 效果展示3. 完整代码1. 用到的API功能用到的API读取图片gocv.IMRead()写入图片gocv.IMWrite()阈值分割gocv.Threshold()图像按位反色gocv.BitwiseNot()提取图像边缘gocv.Canny()详细的用法可以查看官方文档:https://pkg.go.dev/gocv.io/x/gocv#section-documentation2. 效果展示原图片:
2021-03-15 10:31:45 1159 2
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人