- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有下面的代码,我想静态编译以在小型操作系统上运行(几乎没有操作系统!在激活保护模式后,我会将机器代码加载到内存中的特定地址)。到目前为止我的尝试还没有成功。首先有可能吗?如果没有,完成这样的事情最简单的方法是什么?
#include <stdio.h>
#define TXT_COLOR 7
#define printf(...) {sprintf(str,__VA_ARGS__);\
int i=0; while(str[i])\
write_string(TXT_COLOR, &str[i++] );}
// sprintf takes printf arguments and format data
// then write_string outputs data to the video buffer
int write_string( int colour, const char *string );
int _start()
{
char str[256]="";
char c='Z';
int j=9;
float f=9.76777;
printf("%d\t%f\t%c\this is a test\n test more!\n\n",j,f,c);
}
int write_string( int colour, const char *string )
{ /* Function to write a character to the video buffer*/
volatile char *videoBuff = (volatile char*)0xB8000;
while( *string != 0 )
{
*videoBuff++ = *string++;
*videoBuff++ = colour;
}
return 0;
}
最佳答案
对于这个答案,我假设微型操作系统是一个非常简单的内核,它启动到 32 位保护模式并且不做太多其他事情。
首先,您的程序存在问题,因为您正在使用 C 标准库中的 sprintf
。恐怕您必须编写自己的 sprintf(相对容易)或将 *libc 的某些实现移植到您的操作系统(稍微更具挑战性)。我建议您在第一次测试时,只需调用原始 write_string
函数即可。我们还在 _start
末尾放置一个无限循环 - 请记住,“从 main 返回”涉及幕后发生的许多事情,这些事情尚未在裸机操作系统上实现:
#define TXT_COLOR 7
int write_string( int colour, const char *string );
int _start() {
write_string(TXT_COLOR, "this is a test");
for (;;);
}
/* Function to write a character to the video buffer*/
int write_string( int colour, const char *string ) {
volatile char *videoBuff = (volatile char*)0xB8000;
while( *string != 0 ) {
*videoBuff++ = *string++;
*videoBuff++ = colour;
}
return 0;
}
使用 Cygwin GCC,我们可以分三个阶段将此源文件(我命名为 prog.c
)编译为原始二进制文件。
首先,我们通过 C 编译器运行它以生成中间目标文件 (prog.o
),确保指定它适用于 32 位机器:
cc -m32 -c -o prog.o prog.c
接下来,我们将 prog.o
提供给链接器,指定 32 位 PE 输出格式(在 Linux 上这将是 32 位 ELF)以及它将加载到内存中的地址(本例中为 2MB)。我们还需要指定哪个函数将作为入口点,即 _start
(GCC 默认情况下在函数名称前添加下划线,因此它的真实名称实际上是 __start
):
ld -mi386pe -Ttext 0x200000 --entry __start -o prog.pe prog.o
最后,我们将 PE 二进制文件 prog.pe
转换为原始、平面二进制文件 (prog.bin
),不需要任何操作系统提供的基础设施即可运行。这是您将加载到内存并直接执行的内容:
objcopy -O binary prog.pe prog.bin
要在尝试从操作系统加载输出之前对其进行完整性检查,请查看反汇编代码:
objdump -d prog.pe
您应该在最顶部看到 _start
函数,其中包含您指定的加载地址。例如:
Disassembly of section .text:
00200000 <__start>:
200000: 55 push %ebp
200001: 89 e5 mov %esp,%ebp
200003: 83 ec 18 sub $0x18,%esp
...
然后确保 prog.bin
反汇编的原始字节与上面的匹配(符号/名称将不可见,因为它们已全部被删除)。例如:
$ objdump -D -b binary -m i386 prog.bin
Disassembly of section .data:
00000000 <.data>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 18 sub $0x18,%esp
...
关于c++ - cygwin 上的 C 编译以面向独立平台,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29859578/
假设我有一个在 cygwin 下编译的应用程序,并且我想在不让用户安装 cygwin 的情况下分发该应用程序。打包可执行文件和 cygwin DLL 就足够了吗? 最佳答案 事情发生了变化。 Cygw
我从一个镜像站点下载了 cygwin,几个月后,当我尝试更新时,我收到一条消息:“当前 ini 文件来自较新版本的 setup-x86_64.exe” 如果我下载了新的 ini 文件,是否也意味着必须
有什么办法可以回去安装旧版本的 Cygwin? 说我想要 1.7.9 版本,但是 setup.exe在 Cygwin 网站上总是指向最新版本? 最佳答案 http://www.cygwin.com/s
我试图从我的C++代码运行这两个.data文件进行分配。我已经获得了所有文件,并且仅打算为程序实现一些功能(所有内容都应能够运行make命令进行编译)。 我曾经运行过MAC,只是刚开始使用Window
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 8年前关闭。 Improve this q
当我尝试对CVS管理的文件使用Emacs 23.2.1下的ediff-revision时,在*ediff-errors*框架中收到以下错误,而不是直接开始到ediff结果: cygwin warnin
我一直在用 Cygwin (许久)。具体来说,我在Win7上使用它(包括gcc/g++)进行开发工作。我最近才注意到现在存在一个 64-bit version . 我没有特定的需求要求我过渡到 64
我从安装程序 2.905 安装了 cygwin 3.1.7 64 位,如果我不使用 grep --color=always 我在终端中看不到彩色输出,即 grep - -color=auto 在我的终
如何使用 cygwin 挂载软盘镜像文件。我想挂载镜像,将文件复制到挂载的驱动器,然后从命令行卸载它。 我知道你可以使用 Virtual Floppy Drive在 Windows 中,但有没有办法在
这个question说明cygwin的软链接(soft link)和ntfs的junctions有些不同。我希望 cygwin 创建一个真正的连接点。我想过运行mklink但是,见鬼,没有mklink
我想设置一组最小的 cygwin 应用程序(ls、diff、path、find、grep),以便它们在没有完整 cygwin 安装的机器上运行。 我假设我需要的只是相关的 *.exe 文件和 *.dl
我的机器设置可以运行 cmake 和 gcc,我想在构建机器上安装具有完全相同的包和参数集的 cygwin,也可能在其他开发机器上。有没有一种方法可以做到这一点,而不必使用提供的 Setup.exe
我正在尝试使用 Cygwin 运行 Nutch。我在设置 JAVA_HOME 时遇到问题。 $ export JAVA_HOME='/cygdrive/f/program files/java/jd
如果您尝试“全局”安装 Composer,则它无法在 Cygwin 中正确运行。 将 composer.phar 放入/usr/local/bin/composer 中,然后尝试运行它会导致错误: C
要为 Cygwin 安装其他软件包,我是否只需要运行 setup.exe再次从包列表中选择? 此外,就安装 2 个 Cygwin 实例或此类问题而言,这样做不会损害我的计算机(我对这些事情有点菜鸟)。
我刚刚安装了 Cygwin,bash 提示符中的主目录看起来位于我的 Z: 驱动器上。这不是我想要的。 如何更改此设置? 最佳答案 Starting with Cygwin 1.7.34 ,建议的方法
cygwin 上的当前目录是 home/myuser。我导航到 cygwin,发现它有一个名为 home/myuser 的目录,我不知道如何导航到桌面。我不想在那里添加桌面目录,而且我无法在根文件夹
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我使用当前版本的 Cygwin,1.7.9-1。 当我输入“$ which python”时,Cygwin 输出“/usr/bin/python”。 为了确认根目录是我的 Windows 7 文件系统
我想在 Windows 中使用 cmd 做类似的事情: start dir c:\ 应打开一个新控制台,并显示 dir c: 的输出。 对于 Cygwin 我尝试了这个: cmd /c start b
我是一名优秀的程序员,十分优秀!