实现一个基于tcc/tlink的简单的编译链接工具

实现一个基于tcc/tlink的简单的编译链接工具

一、基础研究

在这里我们需要提供一套新的c语言开发工具cc,它支持的c程序不是从main开始运行而是从CMain开始运行。

书上已经对该工具程序进行了需求分析:(1)要在屏幕中间显示彩色的字符串;(2)等待用户输入,按下任意键后开始运行程序员写的程序。

也给出了由需求分析进行的功能分析:代码文件main.obj实现打印字符串、等待输入、调用程序的功能。编译链接文件cc.exe实现调用tcc编译文件、调用tlink连接文件的功能。

新建文件夹,在其中实现main.c如图:

 实现一个基于tcc/tlink的简单的编译链接工具

main.c编译成main.obj文件,并将tcc.exetlink.exe以及编译连接所需文件都拷贝到文件夹中。

这里我们要实现一个编译连接程序cc.cc.bat功能相同。

那么首先来看看什么是批处理文件:批处理就是对某对象进行批量的处理。批处理文件的扩展名为.bat。在“命令提示”下键入批处理文件的名称,或者双击该批处理文件,系统就会调用Cmd.exe运行该批处理程序。我们来看看c.bat的内容:

 实现一个基于tcc/tlink的简单的编译链接工具

这里@表示不显示@后面的命令,echo是一条批处理指令,echo off是关闭回显功能,即后面的语句执行时都不会在屏幕上显示。%1表示传过来的参数。

但是这里批处理使用了dos命令tcc和tlink,而dos命令是不能直接写在c程序里的,能否在c程序里使用dos命令呢?我们来看system函数的功能,它可以发出一个dos命令,如我们要在c程序里使用命令tcc main,可以用system(“tcc main”);来实现。这里还要用到的一个函数strcat,可以把一个字符串添加到另一个字符串结尾处,覆盖另一个字符串结尾处的‘\0’)并添加‘\0’,合成一个完整的字符串。

一个参考程序putarg.c,我们来看看它的内容:

 实现一个基于tcc/tlink的简单的编译链接工具

这个程序的作用是将arg字符数组的值作为一个字符串输出,而且我们要注意这里的参数arg是一个二阶指针,它的作用是什么呢?我们来运行一下:

 实现一个基于tcc/tlink的简单的编译链接工具

 

首先输出了当前的绝对路径,然后输出了我们加在后面的参数,这说明程序是将命令行的参数名作为字符串即字符数组的形式来处理的,*arg的值为参数的字符串的首地址,而**arg的值是字符串的每一个字符。为什么这里n代表命令行参数的个数,arg指向参数的首地址呢?查找资料可知这是main函数不是作为普通函数来使用的,所以它的参数是有特殊用途的。main函数如果带参有两个参数,那么第一个表示参数的个数;第二个参数中argv[0]为自身运行目录路径和程序名,argv[1]指向第一个参数、argv[2]指向第二个参数、等等。

那么我们就可以通过使用带参数的main函数接收我们要编译连接的c文件名,然后将它用strcat进行处理,在用system执行进行编译连接。

编写程序如下:

 实现一个基于tcc/tlink的简单的编译链接工具

这里用数组abcd存储批处理文件里不用改的部分字符串。在开始进行判断,如果n小于2,说明在命令行没有输入要编译的文件名,则提示错误信息并返回。

之后将要编译的文件名加在数组a的后面,形成一句完整的tcc编译语句,将目标文件编译成obj文件。因为arg指针指向的第一个值是本程序的绝对路径,即arg[0]的值是本程序的绝对路径,而arg[1]是存储要编译的文件的字符串的首地址。然后用system执行数组a存放的tcc编译语句。

之后要判断字符串是否结束,如果未结束,则判断字符是否为’.’,因为我们如果在命令行输入的参数是XXX.c,那么tcc时后面加XXX.c是正确的,但是在tlink语句里面加XXX.c是错误的,应该用XXX或者XXX.obj,为了简便我们就使用名字。然后将“.”改成转义字符“\0”表示字符串已经结束。

之后再用strcattlink连接语句拼接好用system执行。

执行结果如下:

 实现一个基于tcc/tlink的简单的编译链接工具

如果不输入文件名则提示错误。如果输入则正确编译连接。运行编译连接生成的exe文件如图:

 实现一个基于tcc/tlink的简单的编译链接工具

 

先在屏幕中间显示显示彩色字符串,再执行CMain函数“welcome to c”,输出字符串“hello world!”。

二、扩展研究

(1)为什么main函数的参数是参数的个数和命令行参数字符串?

答:我认为是参数是在程序跳转到main函数之前初始化时将命令行的参数的字符串地址传递到栈里,再在main函数里通过栈调用。

三、研究总结

今天我们自己基于tcctlink实现了一个编译连接工具cc,它的功能与tcc相似,都是编译连接程序,只是多出了显示欢迎字符串和等待输入再执行程序的功能。向下看,其本质还是tcc的功能,我们并没有真正地实现一个编译器和连接器,向上看,这个程序的实现是一个不断集成的过程,再加上别的功能的obj文件可以组合成更大更丰富的程序。

这一章对共性和个性的分离和封装更加清晰了:共性被封装在编译工具里,个性由要编译的程序实现,按照这个思路,我们可以开发出功能更强大的编译连接工具。

这一张我觉得学习了一个很重要的函数system,我们可以通过程序来调用操作系统的功能,它与我们传统的思维是不同的,我觉得操作系统打开软件执行,软件实现功能后返回操作系统,而这里软件可以调用操作系统的功能,这使我们写的程序可以实现更强大的功能。这种操作是由顶层向底层的调用。

转载于:https://www.cnblogs.com/stormpeach/p/4364007.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/109507.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • mysql useradd_useradd 创建用户

    mysql useradd_useradd 创建用户useradd创建用户1.命令功能useradd创建一个新用户或者更改默认新用户信息。2.语法格式useraddoptionusernameuseradd-Doption参数选项选项选项说明-c新用户passwd文件中的说明栏(冒号分割第5栏)-d新用户的登录时的家目录-e用户被禁用时间。零时账号日期YYYY-MM-DD格式。-g指定用户对应组,用户组必须为系统现有组名称。-…

    2022年10月24日
  • c++ stl源码剖析_stl源码 qt源码

    c++ stl源码剖析_stl源码 qt源码C++stl库手写前言序列式关联式容器适配器ListVector函数dequestringstackqueuebitset关联式容器setmultisetmultiset算法库仿函数前言stl版本abcd,四个版本,接口肯定是一样的代码复用性强,效率高,通用性高,vectordeque他有六个组件,空间配置器,容器,迭代器,算法,仿函数,容器适配器容器和算法中间,靠迭代器连接算法为了通用性,有辅助的东西,让算法通用,也就是使用仿函数仿函数就是一个对象容器通过适配器,可以相

    2022年10月15日
  • Linux之telnet命令[通俗易懂]

    Linux之telnet命令[通俗易懂]telnet命令通常用来远程登录,默认端口是23。telnet程序是基于TELNET协议的远程登录客户端程序。Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主

  • 3.Eclipse创建第一个Java项目[通俗易懂]

    3.Eclipse创建第一个Java项目[通俗易懂]1.在桌面上双击eclipse快捷键,打开软件,出现一个界面2.这个界面是选择eclipse的工作空间,简单来说就是选择Java项目放在磁盘上的哪个位置上,可以点击默认的,也可以自己创建新的文件夹,然后点击Launch3.在主页面上点击File->New->JavaProject创建Java新项目4.在弹出的窗口的Projectname位置处,输入自己项目的名称…

  • KL散度、JS散度、Wasserstein距离[通俗易懂]

    KL散度、JS散度、Wasserstein距离[通俗易懂]1.KL散度KL散度又称为相对熵,信息散度,信息增益。KL散度是是两个概率分布P和Q差别的非对称性的度量。KL散度是用来度量使用基于Q的编码来编码来自P的样本平均所需的额外的位元数。典型情况下,P表示数据的真实分布,Q表示数据的理论分布,模型分布,或P的近似分布。定义如下:DKL(P//Q)=−∑x∈XP(x)log1P(x)+∑x∈XP(x)log1Q(x)DKL(…

  • Jenkins(6)测试报告邮件发送

    Jenkins(6)测试报告邮件发送前言前面已经实现在jenkins上展示html的测试报告,接下来只差最后一步,把报告发给你的领导,展示你的劳动成果了。安装EmailExtensionPlugin插件jenkins首页-

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号