- 后端
- 前端
- 开发工具
【免费下载链接】compiler-explorer
Run compilers interactively from your web browser and interact with the assembly
本文以 Compiler Explorer 官方文档 docs/TurboC.md 为核心,完整讲解如何在 Linux 环境下借助 Dosbox 将经典 DOS 时代的 Turbo C 编译器接入 Compiler Explorer,涵盖环境准备、C 盘目录规划、turboc.properties配置参数逐项说明,并结合仓库源码剖析其底层调用链与汇编解析原理。读完本文,你将掌握一套可直接复制的 Turbo C 编译服务搭建方案,并理解为何需要特殊处理 DOS 换行符、文件名大小写与编译器选项解析。
为什么需要 Dosbox?
Turbo C 是 Borland 于 1980 年代末推出的 16 位 DOS 编译器,其可执行文件TCC.EXE只能在 DOS 环境(或 DOS 模拟器)中运行,无法在现代 Linux 上直接以原生进程方式调用。Compiler Explorer 的解决方案是:在编译请求的“外壳”中使用Dosbox(一款开源的 DOS 模拟器)来装载 Turbo C,编译器前端仍复用 Compiler Explorer 标准的编译-解析-展示链路。从源码结构看,这一思路被抽象为两层类:
- lib/compilers/dosbox-compiler.ts 中的
DosboxCompiler:通用的 Dosbox 驱动基类,负责挂载目录、执行TCC.EXE、回收标准输出; - lib/compilers/turboc.ts 中的
TurboCCompiler:Turbo C 专属子类,定义turboc编译器类型键、过滤选项、输出文件命名与参数解析器。
前置条件准备
要运行 Turbo C 编译器,按文档 docs/TurboC.md 需要准备两样东西:
- Dosbox:最简单的安装方式是通过操作系统包管理器,例如 Debian/Ubuntu 系:
sudo apt install dosbox - Turbo C 安装:如果你手上有 3 张安装盘(安装介质),先用 Dosbox 把它们安装到一个单独目录中。安装完成后需要建立一个充当 DOS 下
C盘的目录,并在其中放置TC子目录。
C 盘目录结构约定
文档强调了一个容易被忽略的约束:假设所有文件名都是大写。也就是说,C盘根目录下应当是TC(大写)而非tc,内部文件也应以 DOS 风格的大写命名。这一约定不是随意为之——它在 Compiler Explorer 源码中有直接体现:TurboCCompiler.getOutputFilename()将输出文件硬编码为EXAMPLE.ASM(见 lib/compilers/turboc.ts),因为 Turbo C/TASM 系工具链会生成大写文件名。
配置:将 Turbo C 接入 Compiler Explorer
Compiler Explorer 采用基于.properties的层级化配置系统,详细机制可参考 docs/Configuration.md:配置文件位于etc/config/目录,遵循CATEGORY.ENVIRONMENT.properties命名规范,defaults为各环境公共底座,local优先级最高(可用--no-local禁用)。Turbo C 的完整示例配置保存在 docs/turboc.properties 中,内容如下:
compilers=&turboc group.turboc.groupName=Turbo C group.turboc.baseName=Turbo C group.turboc.compilers=turboc201 group.turboc.compilerType=turboc group.turboc.isSemVer=true group.turboc.demangler= group.turboc.supportsBinary=false group.turboc.supportsBinaryObject=false group.turboc.supportsExecute=false compiler.turboc201.semver=2.01 compiler.turboc201.exe=/home/user/tc201/TC/TCC.EXE compiler.turboc201.root=/home/user/tc201 compiler.turboc201.dosbox=/usr/bin/dosbox三个必须检查的路径参数
文档特别提醒:务必确保.dosbox、.root、.exe三个路径正确。它们在DosboxCompiler构造函数中被显式读取(lib/compilers/dosbox-compiler.ts):
| 属性 | 含义 | 示例值 | 源码读取方式 |
|---|---|---|---|
compiler.<id>.dosbox | Dosbox 可执行文件的绝对路径 | /usr/bin/dosbox | compiler.<id>.dosbox属性 |
compiler.<id>.root | DOSC盘的根目录(宿主机路径) | /home/user/tc201 | compiler.<id>.root属性 |
compiler.<id>.exe | 指向真正的TCC.EXE | /home/user/tc201/TC/TCC.EXE | 标准compiler.<id>.exe属性 |
.root与.exe的关系是:.root指向宿主文件系统中作为 DOSC盘的目录,TCC.EXE位于其下的TC子目录中,所以示例中.root=/home/user/tc201、.exe=/home/user/tc201/TC/TCC.EXE。
其余配置项说明
compilers=&turboc:把turboc组注册进compilers列表(&为引用语法);group.turboc.groupName=Turbo C/baseName=Turbo C:界面与工具链显示名;group.turboc.compilers=turboc201:该组内唯一编译器实例的 ID;group.turboc.compilerType=turboc:关键项,决定实例化TurboCCompiler类,其静态键key返回'turboc',并在 lib/compilers/_all.ts 中注册;group.turboc.isSemVer=true:启用语义化版本解析,配合compiler.turboc201.semver=2.01在界面上显示版本 2.01(该属性以字符串形式保留,不会被toProperty转为数字,参见 docs/Configuration.md);supportsBinary=false/supportsBinaryObject=false/supportsExecute=false:禁用二进制/对象文件输出与执行功能——16 位 DOS 程序无法在现代容器内执行,文档与配置均如此设定;demangler=:不启用名字改编还原。
源码级原理:DosboxCompiler 如何驱动编译
配置只是第一步,真正的魔力在DosboxCompiler的exec与getDosboxArgs中(lib/compilers/dosbox-compiler.ts)。它把一次编译转换成一段批处理式的 Dosbox 命令序列:
dosbox -c "mount c /home/user/tc201" \ -c "mount d <临时目录>" \ -c "PATH=%PATH%;C:\TC" \ -c "d:" \ -c "TCC <编译参数> > STDOUT.TXT" \ -c "exit"逐条解读:
mount c <root>:把宿主机的C盘根目录挂载为 DOSC:;mount d <临时目录>:把 Compiler Explorer 生成的临时工作目录挂载为 DOSD:,源码文件就写在这里;PATH=%PATH%;C:\TC:在 DOS 的 PATH 中加入C:\TC(binPath由path.relative(this.root, dirname(exe))计算得出),使TCC.EXE可被直接调用;d::切换到D:盘——这正是runCompiler重写参数的原因:它把输入文件的绝对路径替换为纯文件名(lib/compilers/dosbox-compiler.ts),因为 DOS 环境下编译器无法理解 Linux 路径;TCC <args> > STDOUT.TXT:执行编译并把 stdout 重定向到临时目录中的STDOUT.TXT;exit:退出 Dosbox。
编译结束后,exec从D:挂载对应的宿主机临时目录中读取STDOUT.TXT作为结果 stdout(lib/compilers/dosbox-compiler.ts)。
三个易被忽视的适配细节
- 无头运行:
getDosboxEnv设置SDL_VIDEODRIVER=dummy,让 Dosbox 在无显示器环境下静默运行,这是服务器部署的关键(lib/compilers/dosbox-compiler.ts); - CRLF 换行转换:
writeAllFiles与writeMultipleFiles在写源码时将\n全部替换为\r\n(lib/compilers/dosbox-compiler.ts),因为 DOS 编译器期望 CRLF 行结束符; - 缓存与超时:
execCompilerCached沿用 Compiler Explorer 的编译缓存机制,并设置了timeoutMs = 0(不限时)以容忍 Dosbox 启动开销(lib/compilers/dosbox-compiler.ts)。
Turbo C 专属行为
TurboCCompiler在基类之上补充了几点(lib/compilers/turboc.ts):
optionsForFilter()返回['-B']:作为“二进制输出”过滤器的专属选项标记;getOutputFilename()固定返回EXAMPLE.ASM:适配 Turbo C 的汇编输出命名习惯(且为全大写);getVersion()支持explicitVersion强制版本,否则实际调用一次 Dosbox 运行TCC.EXE获取版本输出;getArgumentParserClass()返回TurboCParser——该解析器以空参数调用编译器来提取选项表(lib/compilers/argument-parsers.ts),因为 Turbo C 不提供--help类参数。
汇编输出解析与源码行映射
Turbo C 生成的是 TASM 风格的汇编文本,格式与现代 GCC 大相径庭,因此仓库专门实现了 lib/parsers/asm-parser-turboc.ts 中的TurboCAsmParser。它通过三组正则识别输出结构:
- 文件标记
^\s+\?debug\s+S\s"(.+)":记录当前源文件; - 行号标记
^;\s+\?debug\s+L\s(\d+):记录当前源码行; - 过程边界
^\w+\sproc\s*near与^\w+\sendp:界定每个函数过程。
解析器据此把每条汇编指令映射回 C 源码的(文件, 行号),从而支撑 Compiler Explorer 的源码↔汇编高亮联动;同时支持directives过滤(剔除?debug伪指令)与binary过滤(此时转交通用AsmParser处理二进制反汇编)。实现中还使用asm.replace(/\u001A$/, '')剔除 DOS 文本文件尾部的 Ctrl-Z 结束符——又一个面向 DOS 输出的细节适配。
语言归属与使用限制
文档在 “More notes” 中给出了三条实战注意事项:
- Turbo C 是纯 C 编译器:它不支持 C++,因此应配置在
c.local.properties(C 语言的本地配置)而非 C++ 的配置文件中; - 默认示例源码会立刻报错:Turbo C 2.01 不支持
//行注释,Compiler Explorer 语言页签自带的默认示例(如 examples/c/default.c)使用了//注释,直接编译会失败,需替换为/* ... */风格的源码; - 旧式 C 的变量声明规则:该版本要求函数内所有变量必须在函数开头的几行内声明完毕(即 C89 风格),不能在使用处声明,编写测试源码时需遵守这一语法约束。
这些限制共同说明:接入 Turbo C 主要用于教学、复古程序移植或对比 16 位 DOS 编译器的生成代码,而非现代 C 开发工作流。
验证与常见排错
完成配置后,可按以下顺序验证:
- 确认 Dosbox 可独立运行:直接执行
dosbox -c "mount c /home/user/tc201" -c exit无报错; - 确认三个属性路径真实存在且权限可读:
.dosbox指向可执行文件、.root指向含TC子目录的目录、.exe指向TCC.EXE; - 启动 Compiler Explorer,在语言下拉中选择C,编译器列表中出现 “Turbo C”,版本显示
2.01; - 粘贴一段仅使用
/* */注释、变量声明集中于函数首部的 C89 代码进行编译,汇编输出应能被正确解析并与源码行联动。
若编译无输出或报错,优先检查:临时目录挂载是否成功、STDOUT.TXT是否生成(可在 Dosbox 配置的临时目录中查看)、源码是否包含//注释或中缀变量声明。整个流程中 Compiler Explorer 只负责组织参数与解析结果,实际“编译”完全发生在 Dosbox 模拟的 DOS 世界内部,理解这一点有助于快速定位故障边界。
- 后端
- 前端
- 开发工具
【免费下载链接】compiler-explorer
Run compilers interactively from your web browser and interact with the assembly
相关推荐
如何在本地部署Compiler Explorer:终极配置指南 🚀
如何在本地部署Compiler Explorer:终极配置指南 🚀 Compiler Explorer是一个强大的交互式编译器探索工具,支持30+编程语言的实
后端前端开发工具Apache SeaTunnel在Kubernetes环境中的部署与运行指南
Apache SeaTunnel在Kubernetes环境中的部署与运行指南 前言 Apache SeaTunnel是一个高性能、分布式、海量数据集成工具,支持
数据集成ETL大数据批处理流处理变更数据捕获PTerm部署指南:在不同环境中配置和运行你的CLI应用
PTerm部署指南:在不同环境中配置和运行你的CLI应用 PTerm是一个现代化的Go模块,专门用于美化控制台输出。它提供了丰富的组件系统,包括图表、进度条、表
开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考