我一直在用C编写内核.我一直在使用GCC交叉编译器,在Windows系统上编写并以16位实模式为目标.我没有可用于编写内核的C库.我已经开始使用一些代码来假设将字符直接打印到屏幕上.这是一个函数来自kernel.c:
int main()
{
char *src = (char *)0xB8000000L;
*src = 'M';
src += 2;
*src = 'D';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我使用GCC编译了我的代码,并使用参数-m16生成将在实模式下运行的代码.我使用这些命令来生成我的kernel.bin:
gcc -ffreestanding -c -m16 kernel.c -o kernel.o
ld -Ttext 0x10000 -o kernel.pe kernel.o
objcopy -O binary kernel.pe kernel.bin
Run Code Online (Sandbox Code Playgroud)
Stack Overflow用户Michael Petch解决了我的链接器问题,但评论代码本身是不正确的.他发表了这样的评论:
除链接器问题外,您是否尝试将旧的TurboC/MSVC 16位代码转换为GCC?我发现(char*)0xB8000000L可疑.如果它是一个真正的16位C编译器,它可能是好的,如果它是(char far*)0xB8000000L.GCC不是一个真正的16位C编译器,并没有旧式远指针的概念.所以,即使你得到这个代码进行编译,这可能不会做你认为它做的,我假设从-m16选项与GCC你正在尝试创建一个实模式16位内核(而不是保护模式一个) )?
我一直在尝试printf在C中为我自己的操作系统实现自己的类似功能.我上面提供的代码只是我理解的一小部分.我在程序集中创建了一个bootloader(8086).
迈克尔是对的吗?如果是这样,我该如何解决这个问题并直接写入视频内存0xb8000?
我阅读了关于GDT(全局描述符表)的教程,该教程将GDT定义为"为内存的某些部分定义基本访问权限的那个".这意味着GDT用于记忆保护.
它是否执行除上述以外的任何其他任务?
是否必须在操作系统中实施GDT?
简而言之,如果有人能够以易于理解的方式详细阐述GDT,那将会更好.
谢谢
我正在使用GCC在Linux环境中学习OS开发.我在Bran的内核开发中了解到,编译时C中的所有函数和变量名都在其相应的汇编源文件中以"_"(下划线)开头.但是当我浏览已编译的C程序的汇编源代码时,我甚至找不到"_main"函数.我执行了以下操作.
cpp sample.c sample.i
gcc -S sample.I
我是Buffer Overflow漏洞的新手,我从一个简单的C程序开始.
码
#include <stdio.h>
#include <strings.h>
void execs(void){
printf("yay!!");
}
void return_input (void)
{
char array[30];
gets(array);
}
int main()
{
return_input();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译阶段
我通过禁用stack protectoras来编译上面的cc程序:
cc test.c -o test -fno-stack-protector
Run Code Online (Sandbox Code Playgroud)
使用elf文件的转储objdump如下:
0804843b <execs>:
804843b: 55 push %ebp
804843c: 89 e5 mov %esp,%ebp
804843e: 83 ec 08 sub $0x8,%esp
8048441: 83 ec 0c sub $0xc,%esp
8048444: 68 10 85 04 08 push $0x8048510
8048449: e8 b2 fe ff ff call 8048300 <printf@plt>
804844e: …Run Code Online (Sandbox Code Playgroud) 我正在经历x86的保护模式部分.我刚刚了解了GDT.之前,我已经研究过进入保护模式(即:使用所有32位地址线)必须启用A20门.那么,启用A20的代码必须是16位吗?最近,当我浏览wiki.osdev网站时,我发现启用A20的代码是用x86汇编编写的.X86汇编产生的32位操作码无法以16位模式加载吗?
请尽可能解释.谢谢.
我是汇编语言的新手.我最近陷入了悲惨的境地.我创建了一个示例汇编程序,如下所示:
head.h
#define _Length_ 0x0A
Run Code Online (Sandbox Code Playgroud)
电源
movw $_LENGTH_, %ax
movw _LENGTH_, %ax
Run Code Online (Sandbox Code Playgroud)
现在两个MOV语句有什么区别?斧头的价值是什么?
我正在使用Ubuntu和GAS汇编程序(AT&T语法).
提前致谢
我一直在学习 Rust 中的引用,发现很难理解引用到底是如何存储在堆栈中的。
考虑下面的程序:
fn main() {
let name = String::from("Somu");
let name_ref = &name;
}
Run Code Online (Sandbox Code Playgroud)
现在,如何在堆栈帧中为这两个变量分配内存?
|--------------------|
| name | 0x1fcd |
|--------------------|
| name_ref | ? |
|--------------------|
Run Code Online (Sandbox Code Playgroud)
因此,由于String存储在堆中,因此我们有堆的地址,其中字符串“Somu”作为变量的值出现name。
现在,name_ref是对 的引用name。用 Rust 术语来说,name_ref借用 指向的值name。
那么,什么 get 作为 的值存储在堆栈帧中呢name_ref?
name堆栈中的地址?或者是其他东西?
有人可以用这个概念丰富我吗?
提前致谢
我浏览了网上有关全局描述符表的许多教程.但我找不到一个详细解释64位描述符中所有字段的站点.此外,我坚持使用GDT中的选择器概念.我知道选择器有一个索引,TI是GDT还是LDT字段.简单来说,选择器与GDT之间的关系是什么?如果可能请详细说明.
谢谢..
我正在学习操作系统开发和课程初学者.我想在实模式环境中构建我的系统,这是一个使用C语言的16位环境.
在C中,我使用函数asm()将代码转换为16位,如下所示:
asm(".code16")
Run Code Online (Sandbox Code Playgroud)
在GCC的语言中生成16位可执行文件(不完全如此).
题:
假设我有两个头文件head1.h和head2.h和main.c文件.main.c文件内容如下:
asm(".code16");
#include<head1.h>
#include<head2.h>
int main(){
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,自从我开始我的代码的命令生成16位可执行文件,然后包括head1.h和head2.h,我需要做的,我创建的所有头文件一样吗?(或)添加asm(".code16");一次是否足够?
操作系统:Ubuntu
编译器:Gnu CC
自从我开始使用8086汇编语言编程以来,我一直在思考这些段和段寄存器.我面临的问题是,我无法看到我脑海中存在哪些细分的视觉图像,因此这些概念对我来说并不清楚.
问题1:
据我所知,在启用了20地址线的16位实模式下,我们可以将物理内存分成16段,每段64KiB.第一部分开始于0x00000.下一段的起始地址是什么.是否会添加0x10000(65536 = 64KiB)?
问题2:
这个问题有点奇怪,但仍然是我唯一的选择.假设我给了一个偏移地址0x6000,我怎样才能找到它所属的段以便解决它.
谢谢
我正在学习OS开发,我处于初级水平.我创建了一个简单的启动加载器 要访问磁盘上的其他文件(比如HDD或USB驱动器),我应该使用哪种寻址模式?(CHS或LBA或INT 13h扩展).
哪种寻址方式非常有效(手段,可以用于大多数驱动器)?
谢谢
我正在尝试开发一个简单的操作系统.到目前为止,我开发的所有程序都可以在一个处理器中运行.但是当我通过一个名为多处理系统的概念时,几乎所有的最新系统都基于这个概念,我有很多疑问.
首先,如何创建可在多处理器系统中运行的程序.它是硬件导向还是程序员特定的?
其次,我学习了并行编程语言,这在多处理系统中很有用,其中Java是一个但C不是.那么在C(Windows)中开发的操作系统如何才能实现多处理?
谢谢.