在独立环境下做C语言和汇编语言的试验的一些感想

Microsoft Visual C++ 1.52(最后一个可以编译16位程序的VC版本) Microsoft Visual C++ 1.52(最后一个可以编译16位程序的VC版本)。这个工具因为比较老,所以可能不是很好找。对于BIOS开发者来说,可能需要这个东西。 立即下载

最近一直在为参加 SUN 公司的编程大赛做准备,自己又在准备软件设计师认证,真是忙得一塌糊涂。关于比赛,我主要去负责软件内核的设计,而我本人也想把软件的内核放到单纯的独立环境(所谓独立环境就是指没有任何操作系统环境,就是BIOS经过 POST(Power On Self Test) 之后直接引导进我的环境,类似操作系统kernel)中去,但是,问题出现了,学计算机的人也许都知道,汇编语言是没有可移植性可言的,而 C 有,但是这只局限于代码,同样的程序,在 UNIX 和 Windows 上编译出的结果是大不相同的,也是互不通用的,而汇编语言,在拥有同一指令集的 CPU 的机子上,不同操作系统下则要好得多,换句话说,就是C语言本身有强大的可移植性,但程序没有(这一点在你看过 Windows/DOS EXE 和 UNIX OUT 文件结构后就非常明白了),这就是说在不同环境下都要去编译源代码来获取相应的程序,但是,我所面临的是没有操作系统的独立环境,不要谈编译,连编译器都不能运行,所以,要面临的一个问题是在某一平台开发程序并移植到独立环境中去!这就需要独立代码,所谓独立代码就是指语言无关,只用到语言,而不依赖语言,事实上,没有任何函数可让你依赖,也就是说,有强大库函数支持的 C 语言现在成为了 C 结构的汇编语言(C++/Java/C#/VB 是想都不要想的,这些语言永远不可能实现脱离 Runtime Libary,尤其是 Java 和 VB/C# 这种虚拟机方式的程序)。
也许,与我的平台有关,我做的试验也许并不适用于其它平台。我选择在 Windows 环境下去开发我的程序,因为相比之下我更了解这位老朋友,而其他的很多朋友则选择在 UNIX 或 Linux 下去开发,那么下面我要说的,也许就是和你们无关了。
我千辛万苦找来了号称是 DOS 下最棒的编程工具的 Visual C++ 1.52c(有人用过么?)和 Turbo C++ 3.0(因为 Turbo C/C++ 系列中只有它支持鼠标),以及MASM 6.15 for DOS,这里需要说明的是,开发独立环境程序必须使用 for DOS 的工具,而任何版本的 WIN 程序都将让你痛苦,因为你将永远摆脱不了 Win32 kernel 的折磨,你将永远看不到你的程序像你想象的那样运行在POST之后。之后,我在 VMware Workstation 5.5.3 上搭建起一个平台,不预装任何 OS,然后用 UltraISO 建立了一个 ISO 文件和虚拟机光驱关联,试图通过光盘直接引导进我的程序,如果成功,则说明我的环境搭建成功。然后,我做了一个标准试验:
首先我简单地利用汇编语言操作 BIOS int16 和 int10 标准输入输出中断实现最简单的 getchar() 和 putchar() 函数,并在主函数中调用,这里需要说明的是,我并没有调用通常的 int86() 函数和 stdio.h 也并没有以 main() 函数作为入口函数,因为这样会产生冲突(在这里做个解释,C语言在编译的时候会选择适当模式的 loader 用 Linker 加以连接,这些 loader 是开发工具提供的,它们是用汇编语言编译好并在适当的时候调用 C 语言中的 main() 函数从而把控制权交给 main() 函数,这就是为什么我们的 C 程序全部要从 main() 函数开始执行的原因),然后我自己用汇编语言编写了一个 loader 引导 C 程序,这里要注意的是,.MODEL 一定要设置成 TINY 并且 langtype 要是 C,而且要禁止 MASM6.15 的 EXPR32 特性并且为了防止冲突,我把程序的入口偏移放在 0100h (因为在0000h:0070h是 BIOS 数据区) 然后我使用 VC 的 Linker 将两个目标文件加以连接得到了一个 16 位实模式的 DOS 程序,将它设置成 ISO 文件的引导程序,开机运行,成功进入我的环境!接下来我们开始有变数的去做对照试验,目的是为了说明我之前的观点,库函数和标准C程序在独立环境无效。我使用 stdio.h 中的标准函数 getchar() 和 putchar() 进行我的实验,首先我编写了最简单的程序:

#include <stdio.h>

int main()
{
    
char i=97
;
    
for(;i<='z';i++
)
    {
        putchar(i);
    }
    putchar(
'/n'
);
    
for
(;;)
        putchar(getchar());
    
return 0
;
}

需要说明的是,我的 VC1.52C 可能存在文件缺失,这段程序无法连接成程序,所以我选择在 TC 下以 TINY 模式编译并连接我的程序(在同样的 Windows 下,这样的变数不会影响结果)得到 TC 所谓 Standard EXE 确有 6KB 之巨,要知道,使用 exe2bin 程序转换的 TINY 模式的程序只有一个程序段,体积应该是非常小的,我刚才试验成功的程序只有 80 字节,而拥有 x86 分区的硬盘 MBR 只不过也只有 446 字节,事实上这应该已经说明了它是不可能成功运行在独立环境的,不过,我还是继续做了,我将它设为引导程序,启动虚拟机,运行失败,从而证明了标准 C 程序在独立环境无效。之后,我把上面程序中 main() 函数改名为 t_main() 函数在 VC 1.52C 中只编译(没有 main() 函数,是不能 Build 的),然后同样与我自己编写的目标文件连接,Linker 发出未定义的外界函数错误:
error L2029: '_putchar' : unresolved external
error L2029: '_getchar' : unresolved external
也就是说,Linker 找不到 putchar() 和 getchar() 的原型。我打开 stdio.h 也并没有发现函数的原型,只是找到了 int __cdecl getchar(void); 和 int __cdecl putchar(int); 这样的定义,这足以说明问题,我们知道,__cdecl 协议是 Windows API 惯用的协议,理论上讲,我们可以猜想库函数在 Windows 中的原型就是 Windows API 函数,至于 getchar() 和 putchar() 关联到哪个系统函数,我们这里不做讨论,但支持我观点的一个论证就是 fopen() 对应 CreateFile()。在没有 OS 的情况下,我们无关联可谈,自然库函数也就形同虚设。
很多时候我总是在听前辈们说起独立环境和独立代码,也见到过不少人们问起能否让 C#/Java/VB 脱离虚拟机,但是现在我才真真正正在体会这些,通过自己的双手去试验,完全可以证明很多东西,也许我上面的试验有纰漏,但是,它已经足以让我们能够去了解计算机上运行的程序需要哪些环境,让我们了解,我们的语言又是基于怎样的一种管理。一个基于 C 的操作系统当然为我们提供了足够的 C 环境,让我们去在 OS 层面之上发挥自己的聪明才智,然而当我们想去深入进 OS 层甚至是底层时,我们才会发现我们能够依靠的越来越少。相反的,当我们走进高层,当我们面对 C/C++/C#/Java/VB 等高级语言的时候我们能使用的已经封装好的函数太多太多,也致使我们很多时候并不能给我们的老朋友更多,相反的,我们却索取了更多,但是我并不希望这样,所以我真真正正想去生活在计算机底层,与我的老朋友面对面的交流。
写在最后:我曾经想去实现 malloc() 和 free() 函数,却发现一个问题,malloc() 函数在寻找可用空间时借助 OS 帮助,所以其原型 API 函数应该调用了 OS 内部内存管理函数,这也是操作系统需要解决的问题之一,而对于我来讲还不知道如何去实现这样的技术,但是有一个想法,那就是去开辟一个很大的结构体数组作为内存空间,并通过我的程序设置结构体里的某些变量将某一段数组设为有用或无用。但是,这样做存在的问题是,如果我的程序不是系统 kernel 就不能开辟太大的空间,否则内存会崩溃,于是,我只能想象中的去使用 DOS 21h 中断的 48h,49h,4ah 功能服务去分配内存(48h:给程序分配一块所需内存块,然后返回该块指针;49h:释放已分配内存块;4ah修改已分配内存块的大小),从而如果我想把我准备参加比赛的程序移植到独立环境,还需要做很多工作,毕竟不只是 malloc() 还有 printf() 等可变参和涉及到转义字符的函数,在没有 stdarg.h 和类型判断函数的情况下一切都要依赖于汇编语言这种我还并不熟悉的语言,但愿 MASM 6.15 提供的 TYPE 伪指令可以帮助我实现类型判断从而我自己可以实现转义字符,但是,可变参数仍然是令我最痛苦的事情。在我继续开发系统曾 kernel 的道路上有多少阴影我还无从知晓,是不是有一天,能在世界某一台计算机上跑起我的操作系统呢?努力中...... 

Microsoft Visual C++ 1.52C The 1.x releases are the only releases of Visual C++ that are capable of running on a 16-bit version of Windows. 支持编写16位Windows程序的VC++的最高版本, 后续版本只支持32位程序开发. 立即下载

相关推荐

c编译器,将C语言编译成masm32汇编语言

前段时间自己业余抽空花了三个月编了一个c语言编译器,将c语言编译成masm32。总共4个文件,2000多行的代码,其中sca.c是词法,p.c生成语法树,table.c是符号表,g.c是转化成具体masm32代码,只支持char,short,int,double四种类型数据,其他的有兴趣的可以自己修改增加,由于masm32限制,目前该编译器只支持局部变量在函数开头定义,全局变量不能和局部变量同名。不支持变量强制转变,也不支持switch语句,个人感觉swich没用,#include不支持,只支持“ ”,现在打包给大家分享,包括源代码(感兴趣的可以自己修改或者转发学习,不允许商业用途),里面还有一些例子,想学习编译原理或者masm32的同志可以看看(特别是学习masm32的,可以把写好的c语言直接编译成masm32代码)!遇到问题可以跟我联系,尽量跟你们回复!

基于MASM汇编语言的文件型病毒防护系统

目录摘要 1Abstract 2。

毕业作品网站 834

操作系统实验项目3

【实验题目】学习C/汇编混合编写操作系统 【实验目的】 将C和汇编语言混合,编写一个简单操作系统。 【实验要求】 clr_screen清除屏幕功能 key_detect按键检测功能: 通过参数指定所按按键是否回显 通过参数指定调用该函数时是否阻塞,即指定函数是等待任意按键按下才返回,还是立即返回 有按键按下返回该按键ascii码,无按键按下返回0 (提示:可以通过0x16中断不同功能号实现是否阻塞的功能) read_floppy读软盘功能: 通过参数指定起始扇区/扇区数目 其他参数及返回值可以自定义 c中实现函数 void print_str_uppercase(char *str): 如果str = NULL,将entry.asm文件中的预定义字符串“success”转换为大写并输出; 如果str != NULL,将str指向的字符串转大写输出; 在entry.asm中调用一次该函数显示“SUCCESS” c中实现函数 int choose(int a, int b, int c, int d): 在entry.asm中调用该函数,输出a, b, c, d中的最大值和最小值。

用C语言写操作系统

尽管我的题目是“用C语言写操作系统”,但是,仅仅使用C语言是写不出操作系统的。我看到很多篇关于自己动手开发操作系统的文章,几乎全来自一篇叫“Write Your Own Operating System Tutorial”英文文章,而且,使用的全是汇编语言。如今能够精通汇编语言的人已属凤毛麟角,而且现代操作系统的主体部分是用C语言写的,难道所谓的“Own Operating System”只能用汇

Flying_Colors的专栏 1万+

图像评价之计算PSNR、SSIM、MSE、LPIPS和NIQE评价指标

如果代码对你的研究有所帮助,请为该仓库点上小星星。

书山有路,学海无涯! 2638

PyTorch转ONNX遇到算子不支持?3种实战解决方案+TensorRT适配技巧

本文针对PyTorch模型导出ONNX时常见的算子不支持问题,提供了从诊断到解决的完整实战指南。首先讲解如何精准定位错误根源,随后详细介绍了三种核心解决方案:注册缺失的符号映射、实现自定义算子,以及为TensorRT开发插件的终极落地方案。文章还分享了构建稳健部署流水线的工程化实践,帮助开发者系统性地解决模型部署中的算子兼容性挑战。

fern8的博客 842

Linux 0.12内核学习之(1)——用MASM编写Boot Sector引导扇区

最近在学习Linux0.12内核,正在读《Linux内核完全剖析》。一开始就被ax86写的引导扇区弄晕了。于是Google了很多资料。最终实验了一晚上终于搞定。下面来看看我们怎么用Windows下的MASM来写个Boot Sector。因为我MASM汇编用的比较熟,所以就用MASM来写,当然,汇编只有语法差异,你用什么来写都没关系。     首先,先来说说计算机怎么启动的。经过一系列BIOS

Linux Kernel Developer 1819

CVPR 2024 LaTeX 模板实战:从匿名提交到图表排版的避坑指南

本文详细解析CVPR 2024 LaTeX模板的使用技巧,涵盖匿名提交设置、pdfLaTeX编译器选择、图表排版优化等关键环节。通过实战案例演示智能引用、公式编号、三线表制作等专业技巧,帮助研究者高效完成论文格式规范,规避常见排版错误。特别针对双栏格式下的图片定位、跨栏表格等复杂场景提供解决方案。

weixin_42561040的博客 453

自己开发X86操作系统--LIUNUXOS

自制X86操作系统Liunux

要把所有那些负面的信息当做对自身行为的评价,而不是对自身价值的评判。 1448

RV1126B SDK移植实战:从DDR配置到USB烧写全解析

本文详细解析了RV1126B SDK移植的核心实战流程,重点攻克了DDR初始化失败与USB烧写两大难题。文章从理解启动流程入手,提供了DDR配置错误的排查步骤、SDK编译配置要点,并深入讲解了USB烧写的完整操作与常见问题解决方案,旨在帮助开发者高效完成系统移植与稳定运行。

weixin_29164497的博客 542

RK3566添加ffpeg【Buildroot系统】

有很多人都发现了RK3566系列的芯片是不可以直接使用ffmpeg官网源码的!会报错: Not a video capture device. /dev/video0: No such device 接下来我们就来解决这个问题!!

honmy18的博客 4069

dsp 实验c语言,dsp实验报告 实验1 ccs入门实验2(c语言的使用)

1、 1 DSP 实验报告实验报告 院 ( 系 ) 名 称 自 动 化 科 学 与 电 气 工 程 学 院 学 生 姓 名 学 号 任 课 老 师 吴 冠 2014 年 6 月 DSP 实验报告 1 实验实验 1 CCS 入门实验入门实验 2(C 语言的使用)语言的使用) 一、一、 实验目的实验目的 1. 学习用标准 C 语言编制程序; 了解常用的 C 语言程序设计方法和组成部 分。 2. 熟悉使...

weixin_42298646的博客 1936

AXI总线详解完结篇

经过几个月的整理和发文,AXI总线详解系列正式迎来最终篇,内容基本涵盖了上一篇文章的全部内容。 所有文章的链接如下: 1、 AXI总线详解 2、AXI总线详解-总线和接口以及协议 3、AXI协议中的通道结构 4、AXI总线详解-AXI4读写操作时序及AXI4猝发地址及选择 5、AXI4交换机制 6、ZYNQ中DMA与AXI4总线-DMA简介 7、AXI总线详解-不同类型的DMA 8、AXI总线详解-DMA内部寄存器的读写方式 9、AXI总线详解-几种应用DMA的场合 10、Altera Scatter-G.

OpenFPGA的博客 5489

关于C语言的独立(freestanding)和托管(hosted)环境

4. 一致性(节选) 两种形式的一致性实现是托管(hosted)的和独立(freestanding)的。符合要求的托管实现应接受任何严格符合要求的程序。符合标准的独立实现应接受任何严格符合标准的程序,其中库条款(第 7 条)中指定的功能的使用仅限于标准头文件<float.h>、<iso646.h>、<limits.h>、<stdalign.h>、<stdarg.h>、<stdbool.h>、<stddef.h>、<stdint.h>和<stdnoreturn.h>。一个符合要求的实现可能有扩展(包括额外的库

lrcno6的编程世界 1347

嵌入式工程师必学(118):MCU的硬件定时器和中断

大多数微处理器都有一个或多个可编程硬件定时器,这些定时器包括对中断的支持。可以有不同类型的计时器,用于不同的应用程序。例如,LPC1768 具有四个 32 位通用定时器、一个看门狗定时器、一个重复中断定时器、一个系统滴答定时器、一个正交编码器接口、6 个 PWM 输出和一个支持中断的实时时钟。硬件定时器用于计时和计数作,允许处理器在 timer 进程运行时继续执行其他进程。硬件定时器是一种使用 clock 信号来增加 register 的电路。

码农17年的博客 211

innovus:像ICC2一样设置placement label

ICC2有placement label/placement rule功能,能控制各种类型cell 之间的spacing规则,包括top和bottom edge的spacing。innovus也有相同的功能,以下示例方便大家了解用法。我们需要给所有OAI* cell之间设置一个spacing rule,让他们不要上下或者挨着。效果如下图,这个spacing指的是同一边的间距,不是cell间距。我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?

m0_61544122的博客 833

DOS的古董美(未完待續)

DOS的古董美 MD DocUmEnT: 3/26/2016 10:26:57 AM by Jimbowhy 当计算机技术越来越先进,越来越快速更新,作为电子FANS,发现这样的现状不仅带给从事这个行业的人更多的便利,还有更多的迷失!而DOS就像是那个本应有活力的游乐园,收集资料的过程中发现,国外确实把DOS当成了计算机世界的大游乐场!国内很多在玩开发板的的同学几乎都不懂得,其实个人电脑才是功能最

5667

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

一步步编写操作系统 23 重写主引导记录mbr

本节我们在之前MBR的基础上,做个稍微大一点的改进,经过这个改进后,我们的MBR可以读取硬盘。听上去这可是个大“手术”呢,我们要将之前学过的知识都用上啦。其实没那么大啦,就是加了个读写磁盘的函数而已,哈哈。怀着兴奋与忐忑的心情,咱们开始吧。 改造不是乱改的,在改之前要有个计划,对将来的程序布局要有个规划,心里有数才行。先说说目前的想法。 我们的MBR是受限于512字节大小的,在那么小的空间中,...

sinolover的专栏 1709

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

若用MASM写操作系统的启动部分如何实现? 其他开发语言 / 汇编语言 - 优快云社区 community.csdn.net

导读: 偶有个笨方法,不过总是可行的,偶也是成功了才几天         希望有参考价值     偶在windows98下写代码,工具DEBUG(windows自带),只有MASM5.0             ;boot.txt,汇编连接成boot.exe   “org   7c00h”是为了让MASM计算标号和变量地址时得到正确值     CSEG           SEGMENT

xu的blog 2271

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

一步步编写操作系统 09 写个mbr

有点不好意思了,说了好久,才说到实质性的东西,好了,赶紧给客官上菜。 代码2-1(c2/a/boot/mbr.S) 1 ;主引导程序 2 ;------------------------------------------------------------ 3 SECTION MBR vstart=0x7c00 4 mov ax,cs 5 mov ds,ax 6 mov es,...

sinolover的专栏 1312

汇编学习(十五)X86汇编学习 (2)MBR为例

我们从《汇编语言》的坑爬出来,又进入到了《实模式到保护模式》的坑中。 MBR : 计算机开机加电自检之后,BIOS 就就尝试读取0面0道1扇区的内容,传统上就是主引导扇区MBR共512B 以0x55 和 0xAA结尾。 然后将启动代码加载到逻辑地址:0x0000:0x7c00 处就是0x07c00处。 代码如下: mov ax,0xb800 ;指向文本模式的显示缓冲区 mov es...

密码小仙女 725

独立式环境与宿主式环境————《标准C语言指南》读书笔记01

独立式环境与宿主式环境————《标准C语言指南》读书笔记01 在编写和转换一个C程序之前,需要考虑它的执行环境,因为这关系到源文件的内容(程序应当如何编写),也关系到转换后的程序能否正常执行。通常有两种不同的执行环境,分别是独立式环境(freestanding environment)和宿主式环境(hosted environment)。 这两种环境的划分基于C在不同领域里的广泛应用。

车子(chezi) 2508

C语言结合汇编开发系统内核

转载于:https://www.cnblogs.com/ZHONGZHENHUA/p/10216660.html

weixin_30362083的博客 211

一个操作系统的是实现之C语言与汇编互相调用

bar.c void myprint(char* msg, int len); int choose(int a, int b) { if(a &gt;= b){ myprint("the 1st ont \n", 13); } else{ myprint("the 2nd one \n", 13); } r...

lhm的博客 1200
上一篇: 还有这么流氓的!
下一篇: 关于上一篇文章的补充
frontgoggle
博客等级 码龄21年 7粉丝 161原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值